@tekus/design-system 5.35.0 → 5.36.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/fesm2022/tekus-design-system-components-carousel.mjs +32 -7
- package/fesm2022/tekus-design-system-components-carousel.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-header.mjs +29 -0
- package/fesm2022/tekus-design-system-components-header.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-modal.mjs +49 -29
- package/fesm2022/tekus-design-system-components-modal.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-process-steps.mjs +24 -3
- package/fesm2022/tekus-design-system-components-process-steps.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-sidebar-layout.mjs +20 -6
- package/fesm2022/tekus-design-system-components-sidebar-layout.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-uploader.mjs +1256 -0
- package/fesm2022/tekus-design-system-components-uploader.mjs.map +1 -0
- package/package.json +9 -1
- package/types/tekus-design-system-components-carousel.d.ts +6 -2
- package/types/tekus-design-system-components-header.d.ts +33 -0
- package/types/tekus-design-system-components-modal.d.ts +30 -12
- package/types/tekus-design-system-components-process-steps.d.ts +16 -1
- package/types/tekus-design-system-components-sidebar-layout.d.ts +11 -1
- package/types/tekus-design-system-components-uploader.d.ts +524 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-uploader.mjs","sources":["../../../projects/design-system/components/uploader/src/tokens/uploader.tokens.ts","../../../projects/design-system/components/uploader/src/composable/upload-strategies.helper.ts","../../../projects/design-system/components/uploader/src/composable/uploader-defaults.helper.ts","../../../projects/design-system/components/uploader/src/composable/uploader-validator.helper.ts","../../../projects/design-system/components/uploader/src/services/uploader-queue.service.ts","../../../projects/design-system/components/uploader/src/sections/file-card.component.ts","../../../projects/design-system/components/uploader/src/sections/file-card.component.html","../../../projects/design-system/components/uploader/src/uploader.component.ts","../../../projects/design-system/components/uploader/src/uploader.component.html","../../../projects/design-system/components/uploader/src/services/uploader-store.service.ts","../../../projects/design-system/components/uploader/src/services/uploader-preview.service.ts","../../../projects/design-system/components/uploader/src/services/upload-transport.service.ts","../../../projects/design-system/components/uploader/src/services/provide-uploader.ts","../../../projects/design-system/components/uploader/tekus-design-system-components-uploader.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport {\n IUploaderPreviewProvider,\n IUploaderStore,\n IUploaderTransport\n} from '../types/uploader-item.types';\n\n/** Queue backing store — provided by `provideUploader()`, actively injected by `UploaderQueueService`. */\nexport const UPLOADER_STORE = new InjectionToken<IUploaderStore>(\n 'UPLOADER_STORE'\n);\n/** Client-side preview/metadata generator — provided by `provideUploader()`, actively injected internally. */\nexport const UPLOADER_PREVIEW_PROVIDER = new InjectionToken<IUploaderPreviewProvider>(\n 'UPLOADER_PREVIEW_PROVIDER'\n);\n/**\n * HTTP transport — provided by `provideUploader()`, but never injected\n * internally. Registered purely so the consumer's own `steps`/\n * `multipart.uploadPart` functions can `inject(UPLOADER_TRANSPORT)` instead\n * of instantiating `HttpClient` themselves.\n */\nexport const UPLOADER_TRANSPORT = new InjectionToken<IUploaderTransport>(\n 'UPLOADER_TRANSPORT'\n);\n","import {\n Observable,\n from,\n throwError,\n EMPTY,\n timer,\n catchError,\n concatMap,\n defaultIfEmpty,\n expand,\n map,\n takeWhile,\n toArray,\n tap,\n last,\n filter\n} from 'rxjs';\n\nimport {\n MultipartConfig,\n UploadFlowConfig,\n UploadStep\n} from '../types/uploader-contracts.types';\nimport { PollingResponse } from '../types/uploader.types';\nimport {\n UploadContext,\n StepParams,\n UploadPartParams\n} from '../types/uploader-params.types';\nimport {\n UploadItem,\n IUploaderStore\n} from '../types/uploader-item.types';\n\nexport interface UploadStrategyParams<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n> {\n item: UploadItem<T>;\n payload: T | undefined;\n context: UploadContext<C>;\n config: UploadFlowConfig<T, C>;\n store: IUploaderStore<T>;\n handleError: (\n id: string,\n err: unknown,\n config: UploadFlowConfig<T, C>,\n context: UploadContext<C>\n ) => void;\n reportProgress: (progress: number, text?: string) => void;\n}\n\n/** Runs `config.steps` one after another, reporting progress as each resolves. */\nexport function runSequentialStepsFlow<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n>(params: UploadStrategyParams<T, C>): Observable<C> {\n const { item, payload, context, config, store, handleError, reportProgress } =\n params;\n const steps = config.steps || [];\n const totalSteps = steps.length;\n\n return from(steps).pipe(\n concatMap((step, index) => {\n return executeStep(\n step,\n { file: item.file, context, payload, item },\n index,\n totalSteps,\n store,\n config,\n reportProgress\n ).pipe(\n catchError((err) => {\n handleError(item.id, err, config, context);\n return throwError(() => err);\n })\n );\n }),\n toArray(),\n map(() => context)\n );\n}\n\n/** Runs `config.multipart`: `init` → chunks sequentially via `uploadPart` → `complete`. */\nexport function runMultipartFlow<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n>(params: UploadStrategyParams<T, C>): Observable<C> {\n const { item, payload, context, config, store, handleError, reportProgress } =\n params;\n const multipart = config.multipart!;\n const chunkSize = multipart.chunkSizeMB * 1024 * 1024;\n const totalChunks = Math.ceil(item.file.size / chunkSize);\n\n return multipart.init({ file: item.file, payload }).pipe(\n map((initResult) => {\n Object.assign(context as Record<string, unknown>, initResult);\n reportProgress(0);\n return { partNumber: 0 };\n }),\n\n expand(({ partNumber }: { partNumber: number }) => {\n if (partNumber >= totalChunks) {\n return EMPTY;\n }\n\n const start = partNumber * chunkSize;\n const end = Math.min(start + chunkSize, item.file.size);\n const chunk = item.file.slice(start, end);\n return executeChunk(\n multipart,\n {\n file: item.file,\n chunk,\n partNumber,\n context,\n payload,\n metadata: item.metadata\n },\n totalChunks,\n store,\n item.id,\n config,\n reportProgress\n );\n }),\n\n takeWhile(({ partNumber }) => partNumber <= totalChunks, true),\n toArray(),\n concatMap(() => {\n const scale = 100 / (config.totalSteps || 1);\n reportProgress(\n Math.round(scale),\n config.resolveText?.('FINISHING') ?? 'FINISHING'\n );\n return multipart.complete({ context, payload }).pipe(\n map(() => {\n return context;\n })\n );\n }),\n catchError((err) => {\n handleError(item.id, err, config, context);\n return throwError(() => err);\n })\n );\n}\n\nexport interface PollingStrategyParams<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n> {\n id: string;\n payload: T | undefined;\n context: UploadContext<C>;\n config: UploadFlowConfig<T, C>;\n store: IUploaderStore<T>;\n handleError: (\n id: string,\n err: unknown,\n config: UploadFlowConfig<T, C>,\n context: UploadContext<C>\n ) => void;\n}\n\n/**\n * Runs `config.polling` after the byte upload succeeds: calls `checkStatus`\n * every `intervalMs`, merging `progress`/`statusText`/`steps`/`stepsStatus`/\n * `stepsTitle`/`stepsDescription`/`stepsCountdownSeconds`/`stepsCountdownLabel`\n * into the item as they arrive, until `status` stops being `'loading'`.\n */\nexport function runPolling<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n>(params: PollingStrategyParams<T, C>): Observable<PollingResponse> {\n const { id, payload, context, config, store, handleError } = params;\n const pollConfig = config.polling!;\n const interval = pollConfig.intervalMs || 3000;\n\n return timer(0, interval).pipe(\n concatMap(() => pollConfig.checkStatus({ context, payload })),\n takeWhile((response) => response.status === 'loading', true),\n map((response) => {\n if (response.status === 'error') {\n throw new Error(response.error || 'POLLING_FAILED');\n }\n\n const updates: Partial<UploadItem<T>> = {};\n if (response.progress !== undefined) {\n updates.progress = response.progress;\n }\n if (response.statusText !== undefined) {\n updates.statusText = response.statusText;\n }\n if (response.steps !== undefined) {\n updates.steps = response.steps;\n }\n if (response.stepsStatus !== undefined) {\n updates.stepsStatus = response.stepsStatus;\n }\n if (response.stepsTitle !== undefined) {\n updates.stepsTitle = response.stepsTitle;\n }\n if (response.stepsDescription !== undefined) {\n updates.stepsDescription = response.stepsDescription;\n }\n if (response.stepsCountdownSeconds !== undefined) {\n updates.stepsCountdownSeconds = response.stepsCountdownSeconds;\n }\n if (response.stepsCountdownLabel !== undefined) {\n updates.stepsCountdownLabel = response.stepsCountdownLabel;\n }\n\n if (Object.keys(updates).length > 0) {\n store.update(id, updates);\n }\n return response;\n }),\n catchError((err) => {\n handleError(id, err, config, context);\n return throwError(() => err);\n }),\n toArray(),\n map((responses) => responses.at(-1)!)\n );\n}\n\nfunction executeStep<T, C extends Record<string, unknown>>(\n step: UploadStep<T, C>,\n params: StepParams<T, C>,\n index: number,\n totalSteps: number,\n store: IUploaderStore<T>,\n config: UploadFlowConfig<T, C>,\n reportProgress: (progress: number, text?: string) => void\n): Observable<C> {\n const scale = 100 / (config.totalSteps || 1);\n return step(params).pipe(\n map((result) => {\n Object.assign(params.context as Record<string, unknown>, result);\n const id = params.item?.id;\n if (id) {\n const progress = Math.round(((index + 1) / totalSteps) * scale);\n reportProgress(progress);\n }\n config.hooks?.onStepComplete?.({\n stepIndex: index,\n context: params.context\n });\n return params.context;\n })\n );\n}\n\nfunction executeChunk<T, C extends Record<string, unknown>>(\n multipart: MultipartConfig<T, C>,\n params: UploadPartParams<T, C>,\n totalChunks: number,\n store: IUploaderStore<T>,\n itemId: string,\n config: UploadFlowConfig<T, C>,\n reportProgress: (progress: number, text?: string) => void\n): Observable<{ partNumber: number }> {\n const scale = 100 / (config.totalSteps || 1);\n return multipart.uploadPart(params).pipe(\n tap((val: number | string | Partial<C>) => {\n if (typeof val === 'number' && totalChunks > 0) {\n const currentPartOffset = (params.partNumber / totalChunks) * scale;\n const chunkContribution = (val / 100) * (scale / totalChunks);\n reportProgress(Math.round(currentPartOffset + chunkContribution));\n }\n }),\n filter(\n (val: number | string | Partial<C>) =>\n typeof val === 'object' && val !== null\n ),\n defaultIfEmpty({} as Partial<C>),\n last(),\n map((result) => {\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n Object.assign(params.context as Record<string, unknown>, result);\n }\n\n const progress =\n totalChunks > 0\n ? Math.round(((params.partNumber + 1) / totalChunks) * scale)\n : Math.round(scale);\n reportProgress(progress);\n return { partNumber: params.partNumber + 1 };\n })\n );\n}\n","import { UploadFlowConfig } from '../types/uploader-contracts.types';\n\n/** Fallback values applied by `mergeConfigWithDefaults` when the consumer omits them. */\nexport const UPLOADER_DEFAULTS = {\n chunkSizeMB: 5,\n concurrencyLimit: 4,\n pollingIntervalMs: 3000\n};\n\n/** Fills in `UPLOADER_DEFAULTS` for whatever `config` leaves unset — never overrides an explicit value. */\nexport function mergeConfigWithDefaults<T, C extends Record<string, unknown>>(\n config: UploadFlowConfig<T, C>\n): UploadFlowConfig<T, C> {\n let refined = { ...config };\n\n if (refined.concurrencyLimit === undefined) {\n refined = {\n ...refined,\n concurrencyLimit: UPLOADER_DEFAULTS.concurrencyLimit\n };\n }\n\n if (refined.multipart) {\n refined = {\n ...refined,\n multipart: {\n ...refined.multipart,\n chunkSizeMB:\n refined.multipart.chunkSizeMB ?? UPLOADER_DEFAULTS.chunkSizeMB\n }\n };\n }\n\n if (refined.polling) {\n refined = {\n ...refined,\n polling: {\n ...refined.polling,\n intervalMs:\n refined.polling.intervalMs ?? UPLOADER_DEFAULTS.pollingIntervalMs\n }\n };\n }\n\n return refined;\n}\n","import { FileRestrictions, RestrictionRule } from '../types/uploader.types';\n\n/** `error` is an `UploaderErrorCode` when `isValid` is `false`. */\nexport interface ValidationResult {\n isValid: boolean;\n error?: string;\n detail?: unknown;\n}\n\n/** Checks a file against `UploadFlowConfig.restrictions` before it's queued. */\nexport class UploaderValidator {\n /**\n * Checks integrity (non-empty) first, then extension/size — `rules` (per-extension\n * `maxSizeMB`) if set, otherwise the legacy `allowedExtensions`/`maxSizeMB` pair.\n */\n static validate(\n file: File,\n restrictions: FileRestrictions\n ): ValidationResult {\n const integrityResult = this.checkFileIntegrity(file);\n if (!integrityResult.isValid) {\n return integrityResult;\n }\n\n return restrictions.rules?.length\n ? this.checkGranularRules(file, restrictions.rules)\n : this.checkLegacyRestrictions(file, restrictions);\n }\n\n private static checkFileIntegrity(file: File): ValidationResult {\n if (file.size === 0) {\n return {\n isValid: false,\n error: 'FILE_CORRUPT',\n detail: { fileName: file.name, fileSize: 0 }\n };\n }\n return { isValid: true };\n }\n\n private static checkGranularRules(\n file: File,\n rules: RestrictionRule[]\n ): ValidationResult {\n const fileName = file.name.toLowerCase();\n const matchingRule = rules.find(rule =>\n rule.extensions.some(ext => fileName.endsWith(ext.toLowerCase()))\n );\n\n return matchingRule\n ? this.checkRuleMaxSize(file, matchingRule)\n : this.buildGranularInvalidFormatResult(fileName, rules);\n }\n\n private static buildGranularInvalidFormatResult(\n fileName: string,\n rules: RestrictionRule[]\n ): ValidationResult {\n return {\n isValid: false,\n error: 'INVALID_FORMAT',\n detail: {\n fileName,\n allowedExtensionsByType: rules.map(rule => rule.extensions)\n }\n };\n }\n\n private static checkRuleMaxSize(\n file: File,\n rule: RestrictionRule\n ): ValidationResult {\n if (rule.maxSizeMB !== undefined && file.size > rule.maxSizeMB * 1024 * 1024) {\n return {\n isValid: false,\n error: 'FILE_TOO_LARGE',\n detail: { fileSize: file.size, maxSizeMB: rule.maxSizeMB }\n };\n }\n return { isValid: true };\n }\n\n private static checkLegacyRestrictions(\n file: File,\n restrictions: FileRestrictions\n ): ValidationResult {\n const maxSizeResult = this.checkLegacyMaxSize(file, restrictions);\n if (!maxSizeResult.isValid) {\n return maxSizeResult;\n }\n\n return this.checkLegacyExtension(file, restrictions);\n }\n\n private static checkLegacyMaxSize(\n file: File,\n restrictions: FileRestrictions\n ): ValidationResult {\n if (\n restrictions.maxSizeMB &&\n file.size > restrictions.maxSizeMB * 1024 * 1024\n ) {\n return {\n isValid: false,\n error: 'FILE_TOO_LARGE',\n detail: { fileSize: file.size, maxSizeMB: restrictions.maxSizeMB }\n };\n }\n return { isValid: true };\n }\n\n private static checkLegacyExtension(\n file: File,\n restrictions: FileRestrictions\n ): ValidationResult {\n const fileName = file.name.toLowerCase();\n const isAllowed =\n !restrictions.allowedExtensions ||\n restrictions.allowedExtensions.some(ext =>\n fileName.endsWith(ext.toLowerCase())\n );\n\n return isAllowed\n ? { isValid: true }\n : this.buildLegacyInvalidFormatResult(fileName, restrictions);\n }\n\n private static buildLegacyInvalidFormatResult(\n fileName: string,\n restrictions: FileRestrictions\n ): ValidationResult {\n return {\n isValid: false,\n error: 'INVALID_FORMAT',\n detail: { fileName, allowedExtensions: restrictions.allowedExtensions }\n };\n }\n}\n","import {\n computed,\n inject,\n Injectable,\n untracked,\n runInInjectionContext,\n Injector,\n signal,\n OnDestroy\n} from '@angular/core';\nimport { toObservable } from '@angular/core/rxjs-interop';\nimport {\n MediaAnalysis,\n UploaderErrorCode,\n UploaderStatus\n} from '../types/uploader.types';\nimport { UploadFlowConfig } from '../types/uploader-contracts.types';\nimport {\n UploadItem,\n AuditEntry,\n IUploaderStore\n} from '../types/uploader-item.types';\nimport { UploadContext } from '../types/uploader-params.types';\nimport {\n UPLOADER_STORE,\n UPLOADER_PREVIEW_PROVIDER\n} from '../tokens/uploader.tokens';\nimport {\n concatMap,\n of,\n Subscription,\n finalize,\n take,\n filter,\n firstValueFrom,\n isObservable,\n catchError,\n Observable,\n throwError\n} from 'rxjs';\nimport {\n runSequentialStepsFlow,\n runMultipartFlow,\n runPolling,\n UploadStrategyParams\n} from '../composable/upload-strategies.helper';\nimport { mergeConfigWithDefaults } from '../composable/uploader-defaults.helper';\nimport { UploaderValidator } from '../composable/uploader-validator.helper';\n\nconst STATUS_KEY_MAP: Partial<Record<UploaderStatus, string>> = {\n loading: 'UPLOAD_IN_PROGRESS',\n success: 'FULL_LOAD',\n error: 'LOAD_ERROR',\n ready: 'READY',\n analyzing: 'ANALYZING',\n transforming: 'TRANSFORMING',\n queued: 'PROCESSING'\n};\n\nconst ERROR_CODES: ReadonlySet<UploaderErrorCode> = new Set([\n 'FILE_CORRUPT',\n 'INVALID_FORMAT',\n 'FILE_TOO_LARGE',\n 'ANALYSIS_FAILED',\n 'PROCESS_FAILED',\n 'EXTERNAL_VALIDATION_FAILED',\n 'POLLING_FAILED',\n 'NO_UPLOAD_STRATEGY_CONFIGURED'\n]);\n\n/**\n * The engine — orchestrates the whole upload flow (validation, analysis,\n * transform, `steps`/`multipart`, `polling`, lifecycle hooks) driven purely\n * by the `UploadFlowConfig` passed to `addToQueue`. Not `providedIn: 'root'`;\n * `provideUploader()` gives each `tk-uploader` its own instance.\n */\n@Injectable()\nexport class UploaderQueueService<\n C extends Record<string, unknown> = Record<string, unknown>\n> implements OnDestroy {\n private readonly store = inject<IUploaderStore<unknown>>(UPLOADER_STORE);\n private readonly previewProvider = inject(UPLOADER_PREVIEW_PROVIDER);\n private readonly injector = inject(Injector);\n private readonly activeSubscriptions = new Map<string, Subscription>();\n private readonly isManualTriggered = signal(false);\n private currentConfig?: UploadFlowConfig<unknown, C>;\n\n public readonly uploadQueue = this.store.uploadQueue;\n\n /** Every state transition recorded so far — not currently surfaced anywhere by default. */\n public readonly auditHistory = signal<AuditEntry[]>([]);\n\n /** Whether any item is actively `loading` right now. */\n public readonly isUploading = computed(() =>\n this.uploadQueue().some((i) => i.status === 'loading')\n );\n\n /** Whether any item is mid-flight (`analyzing`/`transforming`/`loading`) — client-side or network work in progress. */\n public readonly isBusy = computed(() =>\n this.uploadQueue().some((i) =>\n ['analyzing', 'transforming', 'loading'].includes(i.status)\n )\n );\n\n /** `!isBusy()` — whether it's safe to close/navigate away without losing in-flight work. */\n public readonly canSafetyClose = computed(() => !this.isBusy());\n\n ngOnDestroy(): void {\n this.clearQueue();\n }\n\n /**\n * Adds one or more files to the queue and starts them through validation →\n * analysis → transform → (auto-start or wait for `startUpload`/`startAllReady`).\n * `config` becomes `currentConfig`, reused by every later call until the next `addToQueue`.\n */\n addToQueue<T = unknown>(\n files: File | File[],\n config: UploadFlowConfig<T, C>\n ): void {\n this.isManualTriggered.set(false);\n const mergedConfig = mergeConfigWithDefaults(config);\n this.currentConfig = mergedConfig as unknown as UploadFlowConfig<\n unknown,\n C\n >;\n const fileList = Array.isArray(files) ? files : [files];\n\n fileList.forEach((file) => {\n const id = crypto.randomUUID();\n const newItem: UploadItem<T> = {\n id,\n file,\n progress: 0,\n status: 'analyzing',\n statusKey: this.getStatusKey('analyzing'),\n statusText: this.getStatusText('analyzing')\n };\n\n this.addAuditEntry(id, 'none', 'analyzing');\n this.store.add(newItem as UploadItem<unknown>);\n mergedConfig.hooks?.onFileAdded?.(file);\n\n untracked(() => {\n if (mergedConfig.restrictions) {\n const result = UploaderValidator.validate(file, mergedConfig.restrictions);\n if (!result.isValid) {\n this.handleError(\n id,\n result.error,\n mergedConfig,\n undefined,\n result.detail,\n 'invalid'\n );\n return;\n }\n }\n this.runAnalysis(id, file, mergedConfig);\n });\n });\n }\n\n private runAnalysis<T>(\n id: string,\n file: File,\n config: UploadFlowConfig<T, C>\n ): void {\n const analysisResource = runInInjectionContext(this.injector, () =>\n this.previewProvider.generatePreview(file)\n );\n\n const sub = toObservable<MediaAnalysis | undefined>(\n analysisResource.value,\n {\n injector: this.injector\n }\n )\n .pipe(\n filter((val) => !!val),\n take(1),\n finalize(() => {\n this.activeSubscriptions.delete(`${id}_analysis`);\n analysisResource.destroy();\n })\n )\n .subscribe((analysis) => {\n if (analysis) {\n this.handleAnalysisResult<T>(id, analysis, config);\n }\n });\n\n this.activeSubscriptions.set(`${id}_analysis`, sub);\n }\n\n private async handleAnalysisResult<T>(\n id: string,\n analysis: MediaAnalysis,\n config: UploadFlowConfig<T, C>\n ): Promise<void> {\n if (!this.uploadQueue().some((i) => i.id === id)) {\n // The item was removed while analysis was still in flight — the store never\n // got `previewUrl`, so `removeFromQueue`'s own revoke couldn't find it either.\n if (analysis.previewUrl?.startsWith('blob:')) {\n URL.revokeObjectURL(analysis.previewUrl);\n }\n return;\n }\n\n if (analysis.analysisError) {\n const errorKey = analysis.technicalError || 'ANALYSIS_FAILED';\n this.handleError(\n id,\n errorKey,\n config,\n {} as unknown as C,\n analysis.technicalError\n );\n return;\n }\n\n this.patchItem(id, {\n previewUrl: analysis.previewUrl,\n previewBlob: analysis.previewBlob,\n previewBase64: analysis.previewBase64,\n metadata: analysis.metadata\n });\n\n const isValid = await this.validateExternalRestrictions<T>(\n id,\n analysis,\n config\n );\n if (!isValid) {\n return;\n }\n\n await this.runTransformation<T>(id, config);\n }\n\n private async validateExternalRestrictions<T>(\n id: string,\n analysis: MediaAnalysis,\n config: UploadFlowConfig<T, C>\n ): Promise<boolean | undefined> {\n if (config.hooks?.validate) {\n let validation: boolean | string;\n const validation$ = config.hooks.validate({\n file: (this.uploadQueue().find((i) => i.id === id) as UploadItem<T>)\n .file,\n metadata: analysis.metadata\n });\n\n if (isObservable(validation$)) {\n validation = await firstValueFrom(\n validation$.pipe(catchError(() => of(false as boolean | string)))\n );\n } else {\n validation = validation$;\n }\n\n if (validation !== true) {\n this.handleError<T>(\n id,\n typeof validation === 'string' && validation\n ? new Error(validation)\n : new Error('EXTERNAL_VALIDATION_FAILED'),\n config,\n {} as unknown as C\n );\n return;\n }\n }\n return true;\n }\n\n private async runTransformation<T>(\n id: string,\n config: UploadFlowConfig<T, C>\n ): Promise<void> {\n if (config.hooks?.onTransform) {\n this.patchItem(id, { status: 'transforming' });\n try {\n const item = this.uploadQueue().find((i) => i.id === id)!;\n const payload = await (\n config.hooks.onTransform as (\n item: UploadItem<unknown>\n ) => Promise<T> | T\n )(item);\n this.patchItem(id, { payload });\n } catch (err) {\n this.handleError<T>(id, err, config, {} as unknown as C);\n return;\n }\n }\n\n const isAutoStart =\n typeof config.autoStart === 'function'\n ? config.autoStart()\n : config.autoStart;\n\n if (isAutoStart !== false || this.isManualTriggered()) {\n this.patchItem(id, { status: 'queued' });\n this.checkConcurrencyAndProcess(config);\n } else {\n this.patchItem(id, { status: 'ready' });\n }\n }\n\n /** Manually starts a single `ready` item (when `autoStart` is `false`). */\n startUpload(id: string): void {\n if (!this.currentConfig) {\n return;\n }\n this.patchItem(id, { status: 'queued' });\n this.checkConcurrencyAndProcess(this.currentConfig);\n }\n\n /** Manually starts every `ready` item at once (when `autoStart` is `false`). */\n startAllReady(): void {\n if (!this.currentConfig) {\n return;\n }\n this.isManualTriggered.set(true);\n this.uploadQueue().forEach((item) => {\n if (item.status === 'ready') {\n this.patchItem(item.id, { status: 'queued' });\n }\n });\n this.checkConcurrencyAndProcess(this.currentConfig);\n }\n\n private checkConcurrencyAndProcess<T>(config: UploadFlowConfig<T, C>): void {\n const limit = config.concurrencyLimit!;\n const activeCount = this.uploadQueue().filter(\n (i: UploadItem<unknown>) => i.status === 'loading'\n ).length;\n\n if (activeCount < limit) {\n const nextItem = this.uploadQueue().find(\n (i: UploadItem<unknown>) => i.status === 'queued'\n );\n if (nextItem) {\n this.processUpload(nextItem as UploadItem<T>, config);\n this.checkConcurrencyAndProcess(config);\n }\n }\n }\n\n private processUpload<T>(\n item: UploadItem<T>,\n config: UploadFlowConfig<T, C>\n ): void {\n const context: UploadContext<C> = {} as unknown as C;\n this.startUploadFlow(item, config);\n\n const subscription = this.getExecutionStream(item, config, context)\n .pipe(\n concatMap(() => {\n if (config.polling) {\n return runPolling<T, C>({\n id: item.id,\n payload: item.payload,\n context,\n config,\n store: this.store as unknown as IUploaderStore<T>,\n handleError: this.handleError.bind(this)\n });\n }\n return of(context);\n }),\n finalize(() => this.finalizeItem(item.id, config))\n )\n .subscribe({\n next: () => {\n this.patchItem(item.id, { status: 'success', progress: 100 });\n config.hooks?.onSuccess?.({ context, payload: item.payload });\n this.checkAllComplete(config);\n },\n error: () => this.checkAllComplete(config)\n });\n\n this.activeSubscriptions.set(item.id, subscription);\n }\n\n private startUploadFlow<T>(\n item: UploadItem<T>,\n config: UploadFlowConfig<T, C>\n ): void {\n this.patchItem(item.id, {\n status: 'loading',\n progress: 0,\n statusText: this.getStatusText('loading')\n });\n config.hooks?.onBeforeStart?.(item.file);\n }\n\n private getExecutionStream<T>(\n item: UploadItem<T>,\n config: UploadFlowConfig<T, C>,\n context: UploadContext<C>\n ): Observable<C> {\n if (!config.multipart && !config.steps?.length) {\n const error = new Error('NO_UPLOAD_STRATEGY_CONFIGURED');\n this.handleError(item.id, error, config, context);\n return throwError(() => error);\n }\n\n const params: UploadStrategyParams<T, C> = {\n item,\n payload: item.payload,\n context,\n config,\n store: this.store as unknown as IUploaderStore<T>,\n handleError: this.handleError.bind(this),\n reportProgress: (progress: number, text?: string) =>\n this.patchItem(item.id, { progress, statusText: text })\n };\n\n return config.multipart\n ? runMultipartFlow<T, C>(params)\n : runSequentialStepsFlow<T, C>(params);\n }\n\n private finalizeItem<T>(id: string, config: UploadFlowConfig<T, C>): void {\n this.activeSubscriptions.delete(id);\n this.checkConcurrencyAndProcess(config);\n }\n\n private extractErrorCode(error: unknown): UploaderErrorCode | undefined {\n if (typeof error === 'string' && ERROR_CODES.has(error as UploaderErrorCode)) {\n return error as UploaderErrorCode;\n }\n if (\n error instanceof Error &&\n ERROR_CODES.has(error.message as UploaderErrorCode)\n ) {\n return error.message as UploaderErrorCode;\n }\n return undefined;\n }\n\n private getErrorText(error: unknown): string {\n const code = this.extractErrorCode(error);\n if (code) {\n return this.resolveUploaderKeyText(code);\n }\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n return this.getStatusText('error');\n }\n\n private resolveUploaderKeyText(key: string): string {\n return this.currentConfig?.resolveText\n ? this.currentConfig.resolveText(key)\n : key;\n }\n\n private handleError<T>(\n id: string,\n error: unknown,\n config: UploadFlowConfig<T, C>,\n context: UploadContext<C> | undefined = undefined,\n detail?: unknown,\n status: UploaderStatus = 'error'\n ): void {\n const errorMessage = this.getErrorText(error);\n\n this.patchItem(\n id,\n {\n status,\n error: errorMessage\n },\n detail\n );\n\n config.hooks?.onError?.({ error, context });\n }\n\n private checkAllComplete<T>(config: UploadFlowConfig<T, C>): void {\n const allTerminal = this.uploadQueue().every((i: UploadItem<unknown>) =>\n ['success', 'error', 'invalid'].includes(i.status)\n );\n if (allTerminal) {\n this.isManualTriggered.set(false);\n config.hooks?.onAllComplete?.();\n }\n }\n\n /**\n * Removes an item outright — revokes its preview blob URL and cancels any\n * in-flight upload subscription first. This is outside `UploadFlowConfig`'s\n * contract on purpose: `tk-uploader` only ever reports a removal request\n * (see `UploaderRemoveRequest`/`removeRequested`), the consumer decides\n * whether/when to actually call this.\n *\n * Deliberately does NOT cancel a still-pending `${id}_analysis` subscription:\n * doing so would drop the analysis result (and any blob URL it already created)\n * on the floor with nothing left to revoke it. Letting it resolve naturally lets\n * `handleAnalysisResult`'s own \"item still in the queue?\" check catch it instead.\n */\n removeFromQueue(id: string): void {\n this.revokeItemPreview(id);\n this.cancelSubscription(id);\n this.store.remove(id);\n }\n\n private revokeItemPreview(id: string): void {\n const item = this.uploadQueue().find((i) => i.id === id);\n if (item?.previewUrl?.startsWith('blob:')) {\n URL.revokeObjectURL(item.previewUrl);\n }\n }\n\n private cancelSubscription(key: string): void {\n const sub = this.activeSubscriptions.get(key);\n if (sub) {\n sub.unsubscribe();\n this.activeSubscriptions.delete(key);\n }\n }\n\n /** Cancels an item's in-flight subscription without removing it — `startUpload` resumes it. */\n pauseUpload(id: string): void {\n this.cancelSubscription(id);\n }\n\n /** Revokes every preview blob URL, cancels every in-flight subscription, and empties the store. */\n clearQueue(): void {\n this.uploadQueue().forEach((item) => {\n if (item.previewUrl?.startsWith('blob:')) {\n URL.revokeObjectURL(item.previewUrl);\n }\n });\n\n this.activeSubscriptions.forEach((sub) => sub.unsubscribe());\n this.activeSubscriptions.clear();\n this.store.clear();\n }\n\n private getStatusKey(status: UploaderStatus): string {\n return STATUS_KEY_MAP[status] || status.toUpperCase();\n }\n\n private getStatusText(status: UploaderStatus): string {\n const key = this.getStatusKey(status);\n if (this.currentConfig?.resolveText) {\n return this.currentConfig.resolveText(key);\n }\n return status;\n }\n\n private patchItem<T>(\n id: string,\n updates: Partial<UploadItem<T>>,\n detail?: unknown\n ): void {\n const currentItem = this.uploadQueue().find((i) => i.id === id);\n if (!currentItem) {\n return;\n }\n\n if (updates.status && updates.status !== currentItem.status) {\n this.addAuditEntry(id, currentItem.status, updates.status, detail);\n updates.statusKey = this.getStatusKey(updates.status);\n updates.statusText ??= this.getStatusText(updates.status);\n }\n\n const cleanUpdates = { ...updates };\n if (cleanUpdates.statusText === undefined) {\n delete cleanUpdates.statusText;\n }\n\n this.store.update(id, cleanUpdates);\n }\n\n private addAuditEntry(\n itemId: string,\n from: UploaderStatus | 'none',\n toStatus: UploaderStatus,\n detail?: unknown\n ): void {\n this.auditHistory.update((history) => [\n ...history,\n {\n itemId,\n from,\n to: toStatus,\n timestamp: Date.now(),\n key: this.getStatusKey(toStatus),\n errorDetail: detail\n }\n ]);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n output\n} from '@angular/core';\n\nimport { ButtonComponent, ButtonSeverity } from '@tekus/design-system/components/button';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { ProgressBarComponent } from '@tekus/design-system/components/progress-bar';\nimport { UploaderStatus } from '../types/uploader.types';\n\n/**\n * Horizontal file card — icon/preview, title, plain progress bar while\n * `status` is `'loading'` (otherwise `statusText`), and a trailing action\n * button. Internal to `tk-uploader`; not part of the public API.\n */\n@Component({\n selector: 'tk-uploader-file-card',\n standalone: true,\n imports: [ButtonComponent, IconComponent, ProgressBarComponent],\n templateUrl: './file-card.component.html',\n styleUrl: './file-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class UploaderFileCardComponent {\n readonly title = input.required<string>();\n readonly status = input.required<UploaderStatus>();\n /** 0-100, shown only while `status` is `'loading'`. */\n readonly progress = input<number>(0);\n readonly previewUrl = input<string | null>();\n /** Fallback icon shown when there's no `previewUrl`. */\n readonly icon = input<string>('folders');\n\n /** Shown instead of the progress bar whenever `status` isn't `'loading'`. */\n readonly statusText = input.required<string>();\n /**\n * Set by the consumer while it's waiting on its own confirmation for this\n * item's removal — this card never confirms anything itself, it only\n * reflects that a decision is pending by disabling the remove button (no\n * double-clicks while waiting).\n */\n readonly isPendingRemoval = input<boolean>(false);\n /**\n * Icon for the trailing button — defaults to the remove affordance\n * (`trash-can`). `tk-uploader` overrides this for its `placeholder` card,\n * where the same button re-opens the file picker instead of removing\n * anything (there's nothing in the real queue to remove).\n */\n readonly trailingIcon = input<string>('trash-can');\n /** Severity for the trailing button — `danger` reads as destructive, `secondary` doesn't. */\n readonly trailingSeverity = input<ButtonSeverity>('danger');\n /**\n * Tooltip/accessible label for the trailing button — this card has no copy of its own\n * (no i18n coupling, same reasoning as `UploadFlowConfig.resolveText`), so it stays\n * unlabeled unless the consumer supplies text here.\n */\n readonly trailingLabel = input<string>();\n /** Emitted on trailing-button click — its meaning depends on `trailingIcon`/context, this card has no opinion on it. */\n readonly dismissed = output<void>();\n\n protected readonly isProcessing = computed(() => this.status() === 'loading');\n}\n","<article class=\"tk-uploader-file-card\" [attr.data-status]=\"status()\">\n <div class=\"tk-uploader-file-card__media\">\n @if (previewUrl()) {\n <img\n [src]=\"previewUrl()\"\n alt=\"File preview\"\n class=\"tk-uploader-file-card__preview\" />\n } @else {\n <tk-icon [icon]=\"icon()\" class=\"tk-uploader-file-card__media-icon\" />\n }\n </div>\n\n <div class=\"tk-uploader-file-card__info\">\n <h4 class=\"tk-uploader-file-card__title\">{{ title() }}</h4>\n\n @if (isProcessing()) {\n <!-- statusText is intentionally hidden while loading: tk-progress-bar only shows a\n number, so with multiple files (no per-item tk-process-steps) there's no textual\n feedback during this state — see uploader.mdx \"Known limitations\". -->\n <div class=\"tk-uploader-file-card__progress\">\n <tk-progress-bar [value]=\"progress()\" size=\"medium\" [showValue]=\"true\" />\n </div>\n } @else {\n <p class=\"tk-uploader-file-card__status-text\">{{ statusText() }}</p>\n }\n </div>\n\n <tk-button\n variant=\"outlined\"\n [severity]=\"trailingSeverity()\"\n size=\"small\"\n [icon]=\"trailingIcon()\"\n [tooltipText]=\"trailingLabel()\"\n class=\"tk-uploader-file-card__remove\"\n [disabled]=\"isPendingRemoval()\"\n (clicked)=\"dismissed.emit()\" />\n</article>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n input,\n output,\n signal,\n viewChild\n} from '@angular/core';\n\nimport { UploadFlowConfig } from './types/uploader-contracts.types';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { ProcessStepsComponent } from '@tekus/design-system/components/process-steps';\nimport { UploaderQueueService } from './services/uploader-queue.service';\nimport { UploaderFileCardComponent } from './sections/file-card.component';\nimport { LoaderPlaceholder } from './types/uploader-placeholder.types';\nimport {\n UploaderRemovePhase,\n UploaderRemoveRequest,\n UploaderStatus\n} from './types/uploader.types';\n\nconst TERMINAL_STATUSES: ReadonlySet<UploaderStatus> = new Set(['success', 'error', 'invalid']);\nconst DEFAULT_STEPS_TITLE = 'Processing';\n\nfunction resolveRemovePhase(status: UploaderStatus): UploaderRemovePhase {\n if (status === 'loading') {\n return 'in-progress';\n }\n return TERMINAL_STATUSES.has(status) ? 'post-upload' : 'pre-upload';\n}\n\n/**\n * Drag-and-drop upload zone with a queue of file cards. Fully agnostic: it\n * has no opinion on *how* a file gets uploaded — validation, upload\n * mechanics, post-upload polling and every lifecycle callback are supplied\n * by the consumer through `config` (`UploadFlowConfig`). Requires\n * `provideUploader()` in the providers of the hosting component (or a parent).\n */\n@Component({\n selector: 'tk-uploader',\n standalone: true,\n imports: [UploaderFileCardComponent, IconComponent, ProcessStepsComponent],\n templateUrl: './uploader.component.html',\n styleUrl: './uploader.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class UploaderComponent<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n> {\n private readonly queueService = inject<UploaderQueueService<C>>(\n UploaderQueueService\n );\n\n /** Idle-state heading, shown before any file is selected. */\n title = input<string>('Drag and drop your file here');\n /** Whether more than one file can be added to the queue at once. */\n multiple = input<boolean>(false);\n /** Idle-state helper text. */\n subtitle = input<string>('or click to browse');\n /** Optional helper line shown below the drop zone while it's empty. */\n helperText = input<string | null>(null);\n /** Label for the optional link appended to `helperText`. */\n helperLinkText = input<string | null>(null);\n /** URL for the optional link appended to `helperText`. */\n helperLinkUrl = input<string | null>(null);\n /** Everything this instance needs to run its flow — see `UploadFlowConfig`. */\n config = input.required<UploadFlowConfig<T, C>>();\n /**\n * Terminal \"existing file\" card shown instead of the idle dropzone while\n * the queue is empty (e.g. edit mode: an already-loaded entity) — see\n * `LoaderPlaceholder`.\n */\n placeholder = input<LoaderPlaceholder<unknown> | null>(null);\n /**\n * Ids the consumer is currently waiting on its own confirmation for (see\n * `removeRequested`). Matching cards disable their remove button so the\n * user can't double-trigger a request while a decision is pending — this\n * component still has no opinion on what that confirmation looks like.\n */\n pendingRemovalIds = input<readonly string[]>([]);\n /**\n * Tooltip/accessible label for a real queue item's remove button — `tk-uploader` has no\n * copy of its own (same reasoning as `UploadFlowConfig.resolveText`), so the button stays\n * unlabeled unless the consumer supplies text here.\n */\n removeLabel = input<string>();\n /** Tooltip/accessible label for the `placeholder` card's trailing (re-upload) button. */\n placeholderReplaceLabel = input<string>();\n\n /** Emitted with the raw `File`(s) as soon as they're picked/dropped — `File[]` when `multiple`, a single `File` otherwise. */\n fileSelected = output<File | File[]>();\n /**\n * Emitted when a file-card's remove button is clicked — `tk-uploader` never\n * removes the item itself. Inspect `phase` to decide whether to confirm\n * (typically for `in-progress`) before calling\n * `UploaderQueueService.removeFromQueue(id)`.\n */\n removeRequested = output<UploaderRemoveRequest>();\n /**\n * Emitted when an item's `tk-process-steps` countdown (`stepsCountdownSeconds`)\n * reaches zero — `tk-uploader` never acts on it itself (doesn't remove the\n * item, doesn't close anything). The consumer decides what that means: close\n * a modal, remove the item, show a toast, etc.\n */\n stepsCountdownFinished = output<string>();\n\n protected fileInput =\n viewChild.required<ElementRef<HTMLInputElement>>('fileInput');\n protected queue = this.queueService.uploadQueue;\n protected isDragging = signal(false);\n\n /**\n * Files already in a terminal state (`success` / `error` / `invalid`) are\n * done — they don't consume capacity anymore even though they stay visible\n * in the queue until manually removed. Capacity is about what's still\n * in-flight, not the size of the visible history.\n */\n private readonly activeCount = computed(\n () => this.queue().filter((item) => !TERMINAL_STATUSES.has(item.status)).length\n );\n\n public isAtCapacity = computed(() => !this.multiple() && this.activeCount() >= 1);\n\n /**\n * Native `accept` attribute for the hidden `<input type=\"file\">`, derived\n * from `config.restrictions` (`rules[].extensions` or `allowedExtensions`)\n * — the same list that actually validates a file — so there is a single\n * source of truth instead of a separate, independently-settable input that\n * could drift out of sync with it. This is only a hint for the OS file\n * picker: it does not filter drag & drop and does not validate anything.\n */\n protected accept = computed(() => {\n const restrictions = this.config().restrictions;\n if (!restrictions) {\n return '';\n }\n const extensions = restrictions.rules?.length\n ? restrictions.rules.flatMap((rule) => rule.extensions)\n : restrictions.allowedExtensions;\n return extensions?.join(',') ?? '';\n });\n\n private dragCounter = 0;\n\n onDragOver(event: DragEvent): void {\n if (this.isAtCapacity()) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n }\n\n onDragEnter(event: DragEvent): void {\n if (this.isAtCapacity()) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter++;\n this.isDragging.set(true);\n }\n\n onDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter--;\n if (this.dragCounter === 0) {\n this.isDragging.set(false);\n }\n }\n\n onDrop(event: DragEvent): void {\n if (this.isAtCapacity()) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter = 0;\n this.isDragging.set(false);\n\n if (event.dataTransfer?.files) {\n this.handleFiles(event.dataTransfer.files);\n }\n }\n\n onFileChange(event: Event): void {\n if (this.isAtCapacity()) {\n return;\n }\n const input = event.target as HTMLInputElement;\n if (input.files) {\n this.handleFiles(input.files);\n }\n }\n\n onCancelItem(id: string): void {\n const item = this.queue().find((i) => i.id === id);\n if (!item) {\n return;\n }\n this.removeRequested.emit({ id, phase: resolveRemovePhase(item.status) });\n }\n\n protected isPendingRemoval(id: string): boolean {\n return this.pendingRemovalIds().includes(id);\n }\n\n protected stepsTitleFor(stepsTitle: string | undefined): string {\n return stepsTitle ?? DEFAULT_STEPS_TITLE;\n }\n\n /** Opens the OS file picker programmatically — a no-op while `isAtCapacity()`. */\n public triggerBrowse(): void {\n if (this.isAtCapacity()) {\n return;\n }\n this.fileInput().nativeElement.click();\n }\n\n private handleFiles(fileList: FileList): void {\n const allFiles = Array.from(fileList);\n if (allFiles.length === 0) {\n return;\n }\n\n const files = this.multiple() ? allFiles : allFiles.slice(0, 1);\n this.queueService.addToQueue(files, this.config());\n this.emitFileSelection(files);\n }\n\n private emitFileSelection(files: File[]): void {\n if (this.multiple()) {\n this.fileSelected.emit(files);\n } else {\n this.fileSelected.emit(files[0]);\n }\n }\n}\n","<div\n class=\"tk-uploader\"\n [class.tk-uploader--dragging]=\"isDragging()\"\n [class.tk-uploader--has-file]=\"queue().length > 0 || !!placeholder()\"\n [class.tk-uploader--disabled]=\"isAtCapacity()\"\n (dragover)=\"onDragOver($event)\"\n (dragenter)=\"onDragEnter($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n <input\n #fileInput\n type=\"file\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n (change)=\"onFileChange($event)\"\n hidden />\n\n @if (queue().length === 0) {\n @if (placeholder()) {\n <!-- Stays a div, not a button: tk-uploader-file-card renders its own trailing\n <button> (replace icon), and a <button> cannot contain another <button>. -->\n <div\n class=\"tk-uploader__placeholder\"\n [class.tk-uploader__placeholder--dragging]=\"isDragging()\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"fileInput.click()\"\n (keydown.enter)=\"fileInput.click()\"\n (keydown.space)=\"fileInput.click(); $event.preventDefault()\">\n <tk-uploader-file-card\n [title]=\"placeholder()!.title\"\n [status]=\"placeholder()!.status\"\n [statusText]=\"placeholder()!.statusText\"\n [progress]=\"placeholder()!.progress ?? 0\"\n [previewUrl]=\"placeholder()!.previewUrl\"\n trailingIcon=\"upload\"\n trailingSeverity=\"secondary\"\n [trailingLabel]=\"placeholderReplaceLabel()\"\n (dismissed)=\"fileInput.click()\" />\n </div>\n } @else {\n <!-- Native <button>, not a div with role=\"button\": no nested interactive\n children here, so the accessible, semantic element is the right fit. -->\n <button type=\"button\" class=\"tk-uploader__idle\" (click)=\"fileInput.click()\">\n <div class=\"tk-uploader__illustration\">\n <tk-icon icon=\"upload\" color=\"primary\" />\n </div>\n\n <div class=\"tk-uploader__text\">\n <h3 class=\"tk-uploader__title\">\n {{ title() }}\n </h3>\n <p class=\"tk-uploader__subtitle\">\n {{ subtitle() }}\n </p>\n </div>\n </button>\n }\n } @else {\n <div class=\"tk-uploader__list\">\n @for (item of queue(); track item.id) {\n <tk-uploader-file-card\n [title]=\"item.file.name\"\n [status]=\"item.status\"\n [statusText]=\"item.statusText\"\n [progress]=\"item.progress\"\n [previewUrl]=\"item.previewUrl\"\n [isPendingRemoval]=\"isPendingRemoval(item.id)\"\n [trailingLabel]=\"removeLabel()\"\n (dismissed)=\"onCancelItem(item.id)\" />\n\n <!-- Gated to !multiple: a step-by-step breakdown per item gets noisy with several\n files uploading at once, so multiple falls back to the plain progress bar even\n when checkStatus returns steps. See uploader.mdx \"Known limitations\". -->\n @if (!multiple() && item.steps) {\n <tk-process-steps\n [steps]=\"item.steps\"\n [title]=\"stepsTitleFor(item.stepsTitle)\"\n [description]=\"item.stepsDescription\"\n [status]=\"item.stepsStatus ?? 'progress'\"\n [showIcon]=\"false\"\n [compact]=\"true\"\n [countdownSeconds]=\"item.stepsCountdownSeconds\"\n [countdownLabel]=\"item.stepsCountdownLabel ?? 'Closing in {seconds}s…'\"\n (countdownFinished)=\"stepsCountdownFinished.emit(item.id)\" />\n }\n }\n </div>\n }\n</div>\n\n@if (queue().length === 0 && helperText()) {\n <div class=\"tk-uploader__helper\">\n <span>{{ helperText() }}</span>\n @if (helperLinkText() && helperLinkUrl()) {\n <a\n [href]=\"helperLinkUrl()\"\n target=\"_blank\"\n rel=\"noopener\"\n class=\"tk-uploader__helper-link\">\n {{ helperLinkText() }}\n </a>\n }\n </div>\n}\n","import { Injectable, signal } from '@angular/core';\nimport {\n IUploaderStore,\n UploadItem\n} from '../types/uploader-item.types';\n\n/**\n * Default `IUploaderStore` — a plain in-memory signal, nothing persisted.\n * Registered by `provideUploader()` under `UPLOADER_STORE`; one instance per\n * `tk-uploader` (not `providedIn: 'root'`), so each gets its own queue.\n */\n@Injectable()\nexport class UploaderStore<T = unknown> implements IUploaderStore<T> {\n private readonly queue = signal<UploadItem<T>[]>([]);\n\n public readonly uploadQueue = this.queue.asReadonly();\n\n add(item: UploadItem<T>): void {\n this.queue.update((items) => [...items, item]);\n }\n\n update(id: string, updates: Partial<UploadItem<T>>): void {\n this.queue.update((items) =>\n items.map((item) => (item.id === id ? { ...item, ...updates } : item))\n );\n }\n\n remove(id: string): void {\n this.queue.update((items) => items.filter((item) => item.id !== id));\n }\n\n clear(): void {\n this.queue.set([]);\n }\n}\n","import { Injectable, resource, ResourceRef } from '@angular/core';\nimport { firstValueFrom, fromEvent } from 'rxjs';\nimport {\n MediaAnalysis,\n MediaMetadata,\n PreviewFrame\n} from '../types/uploader.types';\nimport { IUploaderPreviewProvider } from '../types/uploader-item.types';\n\n/**\n * Default `IUploaderPreviewProvider` — generates a client-side preview/\n * metadata pass during `analyzing` (dimensions for images/video, duration\n * for audio/video, a downscaled preview frame), entirely in the browser\n * with no network call. Registered by `provideUploader()` under\n * `UPLOADER_PREVIEW_PROVIDER`.\n */\n@Injectable()\nexport class UploaderPreviewProvider implements IUploaderPreviewProvider {\n /** Kicks off the analysis as an Angular `resource()`, re-run if `file` changes identity. */\n generatePreview(file: File): ResourceRef<MediaAnalysis | undefined> {\n return resource({\n params: () => file,\n loader: ({ params: f }) => this.analyzeFile(f)\n });\n }\n\n private async analyzeFile(file: File): Promise<MediaAnalysis> {\n const type = this.normalizeMimeType(file);\n try {\n return await this.dispatchByType(file, type);\n } catch (error) {\n return this.createErrorResult(file, type, error);\n }\n }\n\n private dispatchByType(file: File, type: string): Promise<MediaAnalysis> {\n if (type.startsWith('image/')) {\n return this.processImageFile(file, type);\n }\n if (type.startsWith('video/')) {\n return this.processVideoFile(file, type);\n }\n if (type.startsWith('audio/')) {\n return this.processAudioFile(file, type);\n }\n return Promise.resolve(\n this.createAnalysisResult(file, type, { size: file.size })\n );\n }\n\n private createAnalysisResult(\n file: File,\n mimeType: string,\n metadata: Omit<MediaMetadata, 'mimeType'>,\n previews?: PreviewFrame\n ): MediaAnalysis {\n return {\n previewUrl: previews?.url || '',\n previewBase64: previews?.base64 || '',\n previewBlob: previews?.blob,\n analysisError: false,\n metadata: { ...metadata, mimeType }\n };\n }\n\n private createErrorResult(\n file: File,\n mimeType: string,\n error: unknown\n ): MediaAnalysis {\n return {\n previewUrl: '',\n previewBase64: '',\n previewBlob: undefined,\n analysisError: true,\n technicalError: this.resolveTechnicalError(mimeType),\n errorDetail: error,\n metadata: { size: file.size, mimeType }\n };\n }\n\n private resolveTechnicalError(mimeType: string): string {\n const errorMap: Record<string, string> = {\n 'image/': 'PROCESS_FAILED',\n 'video/': 'PROCESS_FAILED',\n 'audio/': 'PROCESS_FAILED'\n };\n return (\n Object.entries(errorMap).find(([key]) => mimeType.startsWith(key))?.[1] ||\n 'ANALYSIS_FAILED'\n );\n }\n\n private resolveMimeFromExtension(file: File): string | undefined {\n const extension = file.name.split('.').pop()?.toLowerCase();\n const mimeMap: Record<string, string> = {\n zip: 'application/zip',\n pdf: 'application/pdf',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n mp4: 'video/mp4',\n mp3: 'audio/mpeg'\n };\n\n return extension ? mimeMap[extension] : undefined;\n }\n\n private normalizeMimeType(file: File): string {\n const byExtension = this.resolveMimeFromExtension(file);\n if (byExtension) {\n return byExtension;\n }\n\n const type = file.type.toLowerCase();\n const isZipVariant =\n type === 'application/x-zip-compressed' ||\n type === 'application/zip-compressed';\n\n return isZipVariant ? 'application/zip' : type || 'application/octet-stream';\n }\n\n private async processImageFile(\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const img = new Image();\n const objectUrl = URL.createObjectURL(file);\n img.src = objectUrl;\n try {\n await this.waitForReady(img, 'load');\n return await this.buildImageAnalysis(img, file, type);\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n }\n\n private async buildImageAnalysis(\n img: HTMLImageElement,\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const preview = await this.captureScaledFrame(\n img,\n img.naturalWidth,\n img.naturalHeight\n );\n return this.createAnalysisResult(\n file,\n type,\n this.buildImageMetadata(img, file),\n preview\n );\n }\n\n private buildImageMetadata(\n img: HTMLImageElement,\n file: File\n ): Omit<MediaMetadata, 'mimeType'> {\n return {\n width: img.naturalWidth,\n height: img.naturalHeight,\n aspectRatio: img.naturalWidth / img.naturalHeight,\n size: file.size\n };\n }\n\n private async processAudioFile(\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const audio = new Audio();\n const objectUrl = URL.createObjectURL(file);\n audio.src = objectUrl;\n try {\n await this.waitForReady(audio, 'loadedmetadata');\n return this.createAnalysisResult(file, type, {\n durationMs: audio.duration * 1000,\n size: file.size\n });\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n }\n\n private async processVideoFile(\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const video = this.createVideoElement(file);\n try {\n await this.waitForReady(video, 'loadedmetadata');\n await this.seekToTime(video, 1);\n return await this.buildVideoAnalysis(video, file, type);\n } finally {\n URL.revokeObjectURL(video.src);\n }\n }\n\n private async buildVideoAnalysis(\n video: HTMLVideoElement,\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const preview = await this.captureScaledFrame(\n video,\n video.videoWidth,\n video.videoHeight\n );\n return this.createAnalysisResult(\n file,\n type,\n this.buildVideoMetadata(video, file),\n preview\n );\n }\n\n private buildVideoMetadata(\n video: HTMLVideoElement,\n file: File\n ): Omit<MediaMetadata, 'mimeType'> {\n return {\n width: video.videoWidth,\n height: video.videoHeight,\n durationMs: video.duration * 1000,\n aspectRatio: video.videoWidth / video.videoHeight,\n size: file.size\n };\n }\n\n private createVideoElement(file: File): HTMLVideoElement {\n const video = document.createElement('video');\n video.muted = true;\n video.playsInline = true;\n video.src = URL.createObjectURL(file);\n return video;\n }\n\n private async captureScaledFrame(\n source: CanvasImageSource,\n naturalWidth: number,\n naturalHeight: number\n ): Promise<PreviewFrame> {\n const { width, height } = this.calculateDimensions(\n naturalWidth,\n naturalHeight\n );\n return this.capturePreviewFrame(source, width, height);\n }\n\n private async capturePreviewFrame(\n source: CanvasImageSource,\n width: number,\n height: number\n ): Promise<PreviewFrame> {\n const canvas = this.prepareCanvas(width, height);\n const ctx = canvas.getContext('2d');\n ctx?.drawImage(source, 0, 0, width, height);\n const base64 = canvas.toDataURL('image/jpeg', 0.8);\n const blob = (await new Promise<Blob | null>(resolve =>\n canvas.toBlob(resolve, 'image/jpeg', 0.8)\n ))!;\n const url = URL.createObjectURL(blob);\n return { url, blob, base64 };\n }\n\n private async waitForReady(\n target: EventTarget,\n readyEvent: string\n ): Promise<void> {\n await Promise.race([\n firstValueFrom(fromEvent(target, readyEvent)),\n firstValueFrom(fromEvent(target, 'error')).then(() => {\n throw new Error('PROCESS_FAILED');\n })\n ]);\n }\n\n private seekToTime(video: HTMLVideoElement, seconds: number): Promise<Event> {\n video.currentTime = seconds;\n return firstValueFrom(fromEvent(video, 'seeked'));\n }\n\n private prepareCanvas(width: number, height: number): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n\n private calculateDimensions(\n originalWidth: number,\n originalHeight: number,\n maxSize = 400\n ): { width: number; height: number } {\n if (originalWidth <= maxSize && originalHeight <= maxSize) {\n return { width: originalWidth, height: originalHeight };\n }\n\n const ratio = originalWidth / originalHeight;\n if (originalWidth > originalHeight) {\n return { width: maxSize, height: maxSize / ratio };\n }\n return { width: maxSize * ratio, height: maxSize };\n }\n}\n","import {\n HttpBackend,\n HttpClient,\n HttpEvent,\n HttpEventType\n} from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { map, Observable } from 'rxjs';\nimport { IUploaderTransport } from '../types/uploader-item.types';\n\n/**\n * Default `IUploaderTransport` — a bare `HttpClient` (via `HttpBackend`, so\n * it bypasses app-level interceptors) that reports upload progress as a\n * plain 0-100 number. Registered by `provideUploader()` under\n * `UPLOADER_TRANSPORT`, for the consumer's own `steps`/`multipart.uploadPart`\n * functions to `inject()` — `tk-uploader` never calls this itself.\n */\n@Injectable()\nexport class TkUploadTransportService implements IUploaderTransport {\n private readonly handler = inject(HttpBackend);\n private readonly http = new HttpClient(this.handler);\n\n upload(\n url: string,\n file: File | Blob,\n method: 'PUT' | 'POST' = 'PUT',\n headers: Record<string, string | string[]> | null = {},\n reportProgress = true,\n observe: 'events' | 'body' = 'events',\n withCredentials = false\n ): Observable<unknown> {\n const finalHeaders = this.resolveHeaders(headers ?? {}, file);\n\n if (observe === 'body') {\n return this.http.request(method, url, {\n body: file,\n headers: finalHeaders,\n reportProgress,\n observe: 'body',\n withCredentials\n });\n }\n\n return this.http\n .request(method, url, {\n body: file,\n headers: finalHeaders,\n reportProgress,\n observe: 'events',\n withCredentials\n })\n .pipe(map((event: HttpEvent<unknown>) => this.mapUploadEvent(event)));\n }\n\n /**\n * Merges the caller's headers with a normalized `Content-Type`\n * (defaulting `.zip`-flavored mime types to `application/zip`).\n * @private\n */\n private resolveHeaders(\n headers: Record<string, string | string[]>,\n file: File | Blob\n ): Record<string, string | string[]> {\n const finalHeaders = { ...headers };\n const contentType = this.resolveContentType(headers, file);\n\n if (contentType) {\n finalHeaders['Content-Type'] = contentType;\n delete finalHeaders['content-type'];\n }\n return finalHeaders;\n }\n\n /**\n * @private\n */\n private resolveContentType(\n headers: Record<string, string | string[]>,\n file: File | Blob\n ): string {\n const contentType =\n this.headerValue(headers['Content-Type']) ||\n this.headerValue(headers['content-type']) ||\n file.type ||\n '';\n const fileName = file instanceof File ? file.name : '';\n const isZip =\n fileName.toLowerCase().endsWith('.zip') ||\n contentType === 'application/x-zip-compressed' ||\n contentType === 'application/zip-compressed';\n\n return isZip ? 'application/zip' : contentType;\n }\n\n /**\n * @private\n */\n private headerValue(value: string | string[] | undefined): string {\n return Array.isArray(value) ? value.join(',') : (value ?? '');\n }\n\n /**\n * @private\n */\n private mapUploadEvent(event: HttpEvent<unknown>): number {\n switch (event.type) {\n case HttpEventType.UploadProgress:\n return Math.round((100 * event.loaded) / (event.total || 1));\n case HttpEventType.Response:\n return 100;\n default:\n return 0;\n }\n }\n}\n","import { Provider } from '@angular/core';\nimport {\n UPLOADER_STORE,\n UPLOADER_PREVIEW_PROVIDER,\n UPLOADER_TRANSPORT\n} from '../tokens/uploader.tokens';\nimport { UploaderStore } from './uploader-store.service';\nimport { UploaderPreviewProvider } from './uploader-preview.service';\nimport { TkUploadTransportService } from './upload-transport.service';\nimport { UploaderQueueService } from './uploader-queue.service';\n\n/**\n * Registers every service `tk-uploader` depends on (queue, preview,\n * transport) — add to the `providers` of the component that hosts\n * `tk-uploader` (or a parent). Each instance gets its own queue.\n */\nexport function provideUploader(): Provider[] {\n return [\n UploaderStore,\n { provide: UPLOADER_STORE, useExisting: UploaderStore },\n UploaderPreviewProvider,\n { provide: UPLOADER_PREVIEW_PROVIDER, useExisting: UploaderPreviewProvider },\n TkUploadTransportService,\n { provide: UPLOADER_TRANSPORT, useExisting: TkUploadTransportService },\n UploaderQueueService\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekus/design-system",
|
|
3
3
|
"description": "Tekus design system library",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.36.0",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"peerDependencies": {
|
|
7
7
|
"@angular/core": "^21.0.0",
|
|
@@ -100,6 +100,10 @@
|
|
|
100
100
|
"types": "./types/tekus-design-system-components-fallback-view.d.ts",
|
|
101
101
|
"default": "./fesm2022/tekus-design-system-components-fallback-view.mjs"
|
|
102
102
|
},
|
|
103
|
+
"./components/header": {
|
|
104
|
+
"types": "./types/tekus-design-system-components-header.d.ts",
|
|
105
|
+
"default": "./fesm2022/tekus-design-system-components-header.mjs"
|
|
106
|
+
},
|
|
103
107
|
"./components/icon": {
|
|
104
108
|
"types": "./types/tekus-design-system-components-icon.d.ts",
|
|
105
109
|
"default": "./fesm2022/tekus-design-system-components-icon.mjs"
|
|
@@ -212,6 +216,10 @@
|
|
|
212
216
|
"types": "./types/tekus-design-system-components-topbar.d.ts",
|
|
213
217
|
"default": "./fesm2022/tekus-design-system-components-topbar.mjs"
|
|
214
218
|
},
|
|
219
|
+
"./components/uploader": {
|
|
220
|
+
"types": "./types/tekus-design-system-components-uploader.d.ts",
|
|
221
|
+
"default": "./fesm2022/tekus-design-system-components-uploader.mjs"
|
|
222
|
+
},
|
|
215
223
|
"./core": {
|
|
216
224
|
"types": "./types/tekus-design-system-core.d.ts",
|
|
217
225
|
"default": "./fesm2022/tekus-design-system-core.mjs"
|
|
@@ -128,7 +128,8 @@ declare const MAX_TAG_LENGTH = 20;
|
|
|
128
128
|
* <tk-carousel
|
|
129
129
|
* [slides]="slides"
|
|
130
130
|
* (slideChange)="onSlideChange($event)"
|
|
131
|
-
* (actionClick)="onActionClick($event)"
|
|
131
|
+
* (actionClick)="onActionClick($event)"
|
|
132
|
+
* (slideClick)="openLightbox($event)">
|
|
132
133
|
* </tk-carousel>
|
|
133
134
|
* ```
|
|
134
135
|
*
|
|
@@ -158,6 +159,8 @@ declare class CarouselComponent {
|
|
|
158
159
|
slideChange: _angular_core.OutputEmitterRef<CarouselSlideChangeEvent>;
|
|
159
160
|
/** Emits the slide whose call-to-action button was clicked. */
|
|
160
161
|
actionClick: _angular_core.OutputEmitterRef<CarouselSlide>;
|
|
162
|
+
/** Emits the slide whose image was clicked, so consumers can open a lightbox. */
|
|
163
|
+
slideClick: _angular_core.OutputEmitterRef<CarouselSlide>;
|
|
161
164
|
/** Reference to the underlying PrimeNG carousel, used for thumbnail navigation. */
|
|
162
165
|
primeCarousel: _angular_core.Signal<Carousel | undefined>;
|
|
163
166
|
/** Zero-based index of the active slide within the visible slides. */
|
|
@@ -187,9 +190,10 @@ declare class CarouselComponent {
|
|
|
187
190
|
onThumbnailClick(event: MouseEvent, index: number): void;
|
|
188
191
|
onImageError(slide: CarouselSlide): void;
|
|
189
192
|
onActionClick(slide: CarouselSlide): void;
|
|
193
|
+
onSlideClick(slide: CarouselSlide): void;
|
|
190
194
|
hasSlideError(slide: CarouselSlide): boolean;
|
|
191
195
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<CarouselComponent, never>;
|
|
192
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<CarouselComponent, "tk-carousel", never, { "slides": { "alias": "slides"; "required": true; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "indicator": { "alias": "indicator"; "required": false; "isSignal": true; }; }, { "slideChange": "slideChange"; "actionClick": "actionClick"; }, never, never, true, never>;
|
|
196
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<CarouselComponent, "tk-carousel", never, { "slides": { "alias": "slides"; "required": true; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "indicator": { "alias": "indicator"; "required": false; "isSignal": true; }; }, { "slideChange": "slideChange"; "actionClick": "actionClick"; "slideClick": "slideClick"; }, never, never, true, never>;
|
|
193
197
|
}
|
|
194
198
|
|
|
195
199
|
export { AUTOPLAY_INTERVAL_MS, CarouselComponent, MAX_DESCRIPTION_LENGTH, MAX_TAG_LENGTH, MAX_TITLE_LENGTH, MAX_VISIBLE_TAGS };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { MenuItem } from 'primeng/api';
|
|
3
|
+
|
|
4
|
+
interface TkHeaderAction {
|
|
5
|
+
icon: string;
|
|
6
|
+
label: string;
|
|
7
|
+
action: () => void;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface TkHeaderDropdownAction {
|
|
11
|
+
type: 'dropdown';
|
|
12
|
+
model: MenuItem[];
|
|
13
|
+
icon?: string;
|
|
14
|
+
label?: string;
|
|
15
|
+
iconPosition?: 'left' | 'right';
|
|
16
|
+
size?: 'small' | 'large';
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
tooltip?: string;
|
|
19
|
+
}
|
|
20
|
+
type TkHeaderAnyAction = TkHeaderAction | TkHeaderDropdownAction;
|
|
21
|
+
|
|
22
|
+
declare class HeaderComponent {
|
|
23
|
+
logoSrc: _angular_core.InputSignal<string | undefined>;
|
|
24
|
+
logoAlt: _angular_core.InputSignal<string>;
|
|
25
|
+
leftActions: _angular_core.InputSignal<TkHeaderAnyAction[]>;
|
|
26
|
+
rightActions: _angular_core.InputSignal<TkHeaderAnyAction[]>;
|
|
27
|
+
protected isDropdown(action: TkHeaderAnyAction): action is TkHeaderDropdownAction;
|
|
28
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HeaderComponent, never>;
|
|
29
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<HeaderComponent, "tk-header", never, { "logoSrc": { "alias": "logoSrc"; "required": false; "isSignal": true; }; "logoAlt": { "alias": "logoAlt"; "required": false; "isSignal": true; }; "leftActions": { "alias": "leftActions"; "required": false; "isSignal": true; }; "rightActions": { "alias": "rightActions"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { HeaderComponent };
|
|
33
|
+
export type { TkHeaderAction, TkHeaderAnyAction, TkHeaderDropdownAction };
|
|
@@ -56,19 +56,19 @@ declare class ModalComponent<T = unknown> implements OnDestroy {
|
|
|
56
56
|
private readonly contentHost;
|
|
57
57
|
private componentRef?;
|
|
58
58
|
/** The dialog ref associated with this modal */
|
|
59
|
-
dialogRef: _angular_core.InputSignal<TkDialogRef<ModalComponent<T>, unknown> | null>;
|
|
59
|
+
readonly dialogRef: _angular_core.InputSignal<TkDialogRef<ModalComponent<T>, unknown> | null>;
|
|
60
60
|
/** The title displayed at the top of the modal */
|
|
61
|
-
title: _angular_core.InputSignal<string>;
|
|
61
|
+
readonly title: _angular_core.InputSignal<string>;
|
|
62
62
|
/** The main content of the modal. Can be a string or a Component Type. */
|
|
63
|
-
content: _angular_core.InputSignal<string | Type<T> | null>;
|
|
63
|
+
readonly content: _angular_core.InputSignal<string | Type<T> | null>;
|
|
64
64
|
/** Array of footer buttons with label, callback, and return value */
|
|
65
|
-
footerButtons: _angular_core.ModelSignal<ModalFooterButton[]>;
|
|
65
|
+
readonly footerButtons: _angular_core.ModelSignal<ModalFooterButton[]>;
|
|
66
66
|
/** Modal size: 'small', 'large', 'medium' or 'full' */
|
|
67
|
-
size: _angular_core.InputSignal<ModalSizeType>;
|
|
67
|
+
readonly size: _angular_core.InputSignal<ModalSizeType>;
|
|
68
68
|
/** Whether the modal can be closed by the user via close button */
|
|
69
|
-
closable: _angular_core.InputSignal<boolean>;
|
|
69
|
+
readonly closable: _angular_core.InputSignal<boolean>;
|
|
70
70
|
/** Whether clicking outside the modal mask closes the modal */
|
|
71
|
-
closeOnOutsideClick: _angular_core.InputSignal<boolean>;
|
|
71
|
+
readonly closeOnOutsideClick: _angular_core.InputSignal<boolean>;
|
|
72
72
|
/**
|
|
73
73
|
* Optional data to be passed as inputs to the dynamic component.
|
|
74
74
|
*/
|
|
@@ -77,15 +77,15 @@ declare class ModalComponent<T = unknown> implements OnDestroy {
|
|
|
77
77
|
* Optional interceptor called before the modal closes.
|
|
78
78
|
* MUST be synchronous. Returns true to allow closing.
|
|
79
79
|
*/
|
|
80
|
-
interceptor: _angular_core.InputSignal<TkCloseInterceptor | undefined>;
|
|
80
|
+
readonly interceptor: _angular_core.InputSignal<TkCloseInterceptor | undefined>;
|
|
81
81
|
/** Computed: whether the content is a simple string */
|
|
82
|
-
isContentString: _angular_core.Signal<boolean>;
|
|
82
|
+
readonly isContentString: _angular_core.Signal<boolean>;
|
|
83
83
|
/** Computed: whether the modal has footer buttons to display */
|
|
84
|
-
hasFooter: _angular_core.Signal<boolean>;
|
|
84
|
+
readonly hasFooter: _angular_core.Signal<boolean>;
|
|
85
85
|
/** Whether the modal should be responsive on mobile screens */
|
|
86
|
-
responsive: _angular_core.InputSignal<boolean>;
|
|
86
|
+
readonly responsive: _angular_core.InputSignal<boolean>;
|
|
87
87
|
/** Visibility flag as Model Signal (allows two-way binding) */
|
|
88
|
-
isOpened: _angular_core.ModelSignal<boolean>;
|
|
88
|
+
readonly isOpened: _angular_core.ModelSignal<boolean>;
|
|
89
89
|
/** Whether the modal content has a scrollbar */
|
|
90
90
|
hasScroll: boolean;
|
|
91
91
|
/** Emits when the modal closes, passing the return value from footer buttons or null */
|
|
@@ -93,6 +93,15 @@ declare class ModalComponent<T = unknown> implements OnDestroy {
|
|
|
93
93
|
private alreadyEmitted;
|
|
94
94
|
private returnValueOnClose;
|
|
95
95
|
constructor();
|
|
96
|
+
/**
|
|
97
|
+
* @summary Orchestrates the reactive dynamic lifecycle.
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
private registerContentLifecycleEffect;
|
|
101
|
+
/**
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
private registerDataSyncEffect;
|
|
96
105
|
/** Computed: calculates modal max-width based on `size` */
|
|
97
106
|
modalMaxWidth: _angular_core.Signal<"67.5rem" | "35rem" | "98vw" | "28.125rem">;
|
|
98
107
|
ngOnDestroy(): void;
|
|
@@ -101,6 +110,10 @@ declare class ModalComponent<T = unknown> implements OnDestroy {
|
|
|
101
110
|
* @private
|
|
102
111
|
*/
|
|
103
112
|
private attachDynamicContent;
|
|
113
|
+
/**
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
private createContentInjector;
|
|
104
117
|
/**
|
|
105
118
|
* @summary Synchronizes incoming data record with the dynamic instance @Inputs.
|
|
106
119
|
* @private
|
|
@@ -126,6 +139,11 @@ declare class ModalComponent<T = unknown> implements OnDestroy {
|
|
|
126
139
|
* @param returnValue (Optional) Value to emit on close.
|
|
127
140
|
*/
|
|
128
141
|
tryClose(returnValue?: unknown): void;
|
|
142
|
+
/**
|
|
143
|
+
* @summary Evaluates the optional close interceptor, then executes closure.
|
|
144
|
+
* @private
|
|
145
|
+
*/
|
|
146
|
+
private resolveInterceptorAndClose;
|
|
129
147
|
/**
|
|
130
148
|
* Evaluates a boolean, Promise or Observable to check if closing is allowed.
|
|
131
149
|
*/
|
|
@@ -4,6 +4,8 @@ type StepState = 'waiting' | 'active' | 'done' | 'error' | 'warning';
|
|
|
4
4
|
interface ProcessStep {
|
|
5
5
|
label: string;
|
|
6
6
|
state: StepState;
|
|
7
|
+
/** Optional secondary line shown below the label — e.g. "Errors detected — check notifications" for a failed step. */
|
|
8
|
+
description?: string;
|
|
7
9
|
}
|
|
8
10
|
/**
|
|
9
11
|
* Overall result of the process:
|
|
@@ -19,6 +21,17 @@ declare class ProcessStepsComponent {
|
|
|
19
21
|
readonly description: _angular_core.InputSignal<string | undefined>;
|
|
20
22
|
readonly icon: _angular_core.InputSignal<string>;
|
|
21
23
|
readonly status: _angular_core.InputSignal<ProcessStepsStatus>;
|
|
24
|
+
/** Whether to show the spinner + icon header while `status` is `progress`. */
|
|
25
|
+
readonly showIcon: _angular_core.InputSignal<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Strips the panel down to just the step list: no padding, and no
|
|
28
|
+
* `title`/`description` header while `status` is `progress` — for hosts
|
|
29
|
+
* that provide their own framing (e.g. a card) and already show the file
|
|
30
|
+
* name elsewhere. The final result view (`success`/`error`/`warning`)
|
|
31
|
+
* still shows its own title/message, since that's the only place the
|
|
32
|
+
* outcome text is surfaced.
|
|
33
|
+
*/
|
|
34
|
+
readonly compact: _angular_core.InputSignal<boolean>;
|
|
22
35
|
/** Specific problems to list inside the result message box (ignored when `status` is `success`). */
|
|
23
36
|
readonly errors: _angular_core.InputSignal<string[]>;
|
|
24
37
|
/** Seconds until the countdown finishes; omit to disable it. */
|
|
@@ -47,10 +60,12 @@ declare class ProcessStepsComponent {
|
|
|
47
60
|
readonly resultColor: _angular_core.Signal<"warning" | "success" | "danger">;
|
|
48
61
|
/** Severity for the message box wrapping `description`/`errors` (success has no box). */
|
|
49
62
|
readonly resultMessageSeverity: _angular_core.Signal<"error" | "warn">;
|
|
63
|
+
/** Severity for the compact terminal banner (`tk-message`) — unlike `resultMessageSeverity`, success gets its own box here. */
|
|
64
|
+
readonly bannerSeverity: _angular_core.Signal<"error" | "success" | "warn">;
|
|
50
65
|
/** `countdownLabel` with `{seconds}` filled in, or `undefined` while the countdown is disabled. */
|
|
51
66
|
readonly countdownText: _angular_core.Signal<string | undefined>;
|
|
52
67
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ProcessStepsComponent, never>;
|
|
53
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ProcessStepsComponent, "tk-process-steps", never, { "steps": { "alias": "steps"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "countdownSeconds": { "alias": "countdownSeconds"; "required": false; "isSignal": true; }; "countdownLabel": { "alias": "countdownLabel"; "required": false; "isSignal": true; }; }, { "countdownFinished": "countdownFinished"; }, never, never, true, never>;
|
|
68
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ProcessStepsComponent, "tk-process-steps", never, { "steps": { "alias": "steps"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "status": { "alias": "status"; "required": false; "isSignal": true; }; "showIcon": { "alias": "showIcon"; "required": false; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "countdownSeconds": { "alias": "countdownSeconds"; "required": false; "isSignal": true; }; "countdownLabel": { "alias": "countdownLabel"; "required": false; "isSignal": true; }; }, { "countdownFinished": "countdownFinished"; }, never, never, true, never>;
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
export { ProcessStepsComponent };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { OnInit, OnDestroy } from '@angular/core';
|
|
3
|
+
import { TkHeaderAction } from '@tekus/design-system/components/header';
|
|
3
4
|
import * as rxjs from 'rxjs';
|
|
4
5
|
import { MenuItem } from 'primeng/api';
|
|
5
6
|
|
|
@@ -18,6 +19,10 @@ declare class SidebarLayoutComponent implements OnInit, OnDestroy {
|
|
|
18
19
|
* If provided, it overrides the service state.
|
|
19
20
|
*/
|
|
20
21
|
isCollapsed: i0.InputSignal<boolean | undefined>;
|
|
22
|
+
/**
|
|
23
|
+
* Actions rendered in the right zone of the header via tk-header.
|
|
24
|
+
*/
|
|
25
|
+
headerActions: i0.InputSignal<TkHeaderAction[]>;
|
|
21
26
|
/**
|
|
22
27
|
* Emitted when the collapsed state changes.
|
|
23
28
|
*/
|
|
@@ -37,6 +42,11 @@ declare class SidebarLayoutComponent implements OnInit, OnDestroy {
|
|
|
37
42
|
* Determines if the sidebar is currently collapsed.
|
|
38
43
|
*/
|
|
39
44
|
get displayCollapsed(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Returns the left actions for tk-header: includes the toggle button
|
|
47
|
+
* only when the sidebar is collapsed or in tablet/mobile mode.
|
|
48
|
+
*/
|
|
49
|
+
get headerLeftActions(): TkHeaderAction[];
|
|
40
50
|
/**
|
|
41
51
|
* Toggles the sidebar state.
|
|
42
52
|
*/
|
|
@@ -55,7 +65,7 @@ declare class SidebarLayoutComponent implements OnInit, OnDestroy {
|
|
|
55
65
|
*/
|
|
56
66
|
handleBackdropClick(): void;
|
|
57
67
|
static ɵfac: i0.ɵɵFactoryDeclaration<SidebarLayoutComponent, never>;
|
|
58
|
-
static ɵcmp: i0.ɵɵComponentDeclaration<SidebarLayoutComponent, "tk-sidebar-layout", never, { "isCollapsed": { "alias": "isCollapsed"; "required": false; "isSignal": true; }; }, { "collapsedChange": "collapsedChange"; }, never, ["[sidebar-content]", "
|
|
68
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<SidebarLayoutComponent, "tk-sidebar-layout", never, { "isCollapsed": { "alias": "isCollapsed"; "required": false; "isSignal": true; }; "headerActions": { "alias": "headerActions"; "required": false; "isSignal": true; }; }, { "collapsedChange": "collapsedChange"; }, never, ["[sidebar-content]", "*"], true, never>;
|
|
59
69
|
}
|
|
60
70
|
|
|
61
71
|
declare class SidebarService {
|