{{'loading-units' | translate}}
+| + |
+ |
+ {{'coding.unit-name' | translate}} | +{{formatUnitName(unit.unitName)}} | +
|---|---|
| + @if (filterValue) { + {{'no-units-matching' | translate}} "{{filterValue}}" + } @else { + {{'no-units-available' | translate}} + } + | +
Kodierschema mit Schemer Version ab 1.5 erzeugen!
' + }; + if (contentSetting.showScore) codeInfo.score = ''; + return codeInfo; + } + + private static getCodeInfoFromCodeAsText(code: CodeData, contentSetting: CodeBookContentSetting): CodeInfo { + const codeAsText = ToTextFactory.codeAsText(code, 'SIMPLE'); + const rulesDescription = contentSetting.hasOnlyManualCoding && !contentSetting.hasClosedVars ? '' : + this.getRulesDescription(codeAsText, code); + const codeInfo: CodeInfo = { + id: `${code.id}`, + label: contentSetting.codeLabelToUpper ? codeAsText.label.toUpperCase() : codeAsText.label, + description: `${rulesDescription}${code.manualInstruction}` + }; + if (contentSetting.showScore) codeInfo.score = codeAsText.score.toString(); + return codeInfo; + } + + private static getRulesDescription(codeAsText: CodeAsText, code: CodeData): string { + let rulesDescription = ''; + codeAsText.ruleSetDescriptions.forEach( + (ruleSetDescription: string) => { + if (ruleSetDescription !== 'Keine Regeln definiert.') { + rulesDescription += `${ruleSetDescription}
`; + } else if (code.manualInstruction === '') rulesDescription += `${ruleSetDescription}
`; + } + ); + return rulesDescription; + } +} diff --git a/projects/ngx-coding-components/src/lib/models/codebook.interfaces.ts b/projects/ngx-coding-components/src/lib/models/codebook.interfaces.ts new file mode 100644 index 0000000..09974dc --- /dev/null +++ b/projects/ngx-coding-components/src/lib/models/codebook.interfaces.ts @@ -0,0 +1,151 @@ +import { VariableInfo } from '@iqbspecs/variable-info/variable-info.interface'; + +/** + * Item metadata for codebook + */ +export interface ItemMetadata { + [key: string]: unknown; +} + +/** + * Settings for codebook content generation + */ +export interface CodeBookContentSetting { + /** Export format (docx or json) */ + exportFormat: string; + /** Missings profile name */ + missingsProfile: string; + /** Include only manual coding */ + hasOnlyManualCoding: boolean; + /** Include general instructions */ + hasGeneralInstructions: boolean; + /** Include derived variables */ + hasDerivedVars: boolean; + /** Include only variables with codes */ + hasOnlyVarsWithCodes: boolean; + /** Include closed variables */ + hasClosedVars: boolean; + /** Convert code labels to uppercase */ + codeLabelToUpper: boolean; + /** Show score */ + showScore: boolean; + /** Hide item-variable relation */ + hideItemVarRelation: boolean; +} + +/** + * Missing code definition + */ +export interface Missing { + /** Missing code */ + code: string; + /** Missing label */ + label: string; + /** Missing description */ + description: string; +} + +/** + * Code information for codebook + */ +export interface CodeInfo { + /** Code ID */ + id: string; + /** Code label */ + label: string; + /** Code description */ + description: string; + /** Code score (optional) */ + score?: string; +} + +/** + * Variable information for codebook + */ +export interface BookVariable { + /** Variable ID */ + id: string; + /** Variable label */ + label: string; + /** Variable source type */ + sourceType: string; + /** General instruction */ + generalInstruction: string; + /** Codes */ + codes: CodeInfo[]; +} + +/** + * Unit data for codebook + */ +export interface CodebookUnitDto { + /** Unit key */ + key: string; + /** Unit name */ + name: string; + /** Variables */ + variables: BookVariable[]; + /** Missings */ + missings: Missing[]; + /** Items (optional) */ + items?: ItemMetadata[]; +} + +/** + * Unit properties for codebook generation + */ +export interface UnitPropertiesForCodebook { + /** Unit ID */ + id: number; + /** Unit key */ + key: string; + /** Unit name */ + name: string; + /** Coding scheme */ + scheme?: string; + /** Scheme type */ + schemeType?: string; + /** Metadata */ + metadata?: { + /** Items */ + items?: ItemMetadata[]; + }; + /** Variables */ + variables?: VariableInfo[]; +} + +/** + * Unit selection item for codebook export UI + */ +export interface UnitSelectionItem { + /** Unit ID */ + unitId: number; + /** Unit name */ + unitName: string; + /** Unit alias */ + unitAlias: string | null; +} + +/** + * Missings profile for selection + */ +export interface MissingsProfile { + /** Profile ID */ + id: number; + /** Profile label */ + label: string; + /** Missings data */ + missings?: Missing[] | string; +} + +/** + * Codebook export configuration + */ +export interface CodebookExportConfig { + /** Selected unit IDs */ + selectedUnits: number[]; + /** Content options */ + contentOptions: CodeBookContentSetting; + /** Selected missings profile ID */ + missingsProfileId: number; +} diff --git a/projects/ngx-coding-components/src/public-api.ts b/projects/ngx-coding-components/src/public-api.ts index 193bd2b..d132810 100644 --- a/projects/ngx-coding-components/src/public-api.ts +++ b/projects/ngx-coding-components/src/public-api.ts @@ -12,3 +12,8 @@ export * from './lib/dialogs/show-coding-dialog.component'; export * from './lib/dialogs/simple-input-dialog.component'; export * from './lib/dialogs/coding-scheme-dialog.component'; export * from './lib/elements/register-elements'; +export * from './lib/codebook-export/codebook-export.component'; +export * from './lib/models/codebook.interfaces'; +export * from './lib/codebook-generator/codebook-generator.class'; +export * from './lib/codebook-generator/codebook-docx-generator.class'; + From 53c9025cfdb68c08bd7409b472b2138260ca19f8 Mon Sep 17 00:00:00 2001 From: jurei733 <67505990+jurei733@users.noreply.github.com> Date: Fri, 13 Mar 2026 10:58:19 +0100 Subject: [PATCH 2/5] Relax Angular peer dependency versions --- package-lock.json | 30 --------------------- projects/ngx-coding-components/package.json | 24 ++++++++--------- 2 files changed, 12 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c19fd6..d7dbeb9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5763,22 +5763,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@schematics/angular/node_modules/chokidar": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", - "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", - "extraneous": true, - "license": "MIT", - "dependencies": { - "readdirp": "^5.0.0" - }, - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@schematics/angular/node_modules/cli-spinners": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", @@ -5842,20 +5826,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@schematics/angular/node_modules/readdirp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", - "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", - "extraneous": true, - "license": "MIT", - "engines": { - "node": ">= 20.19.0" - }, - "funding": { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - }, "node_modules/@schematics/angular/node_modules/stdin-discarder": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.3.1.tgz", diff --git a/projects/ngx-coding-components/package.json b/projects/ngx-coding-components/package.json index cb8f7b2..34becb2 100644 --- a/projects/ngx-coding-components/package.json +++ b/projects/ngx-coding-components/package.json @@ -18,17 +18,17 @@ "homepage": "https://github.com/iqb-berlin/coding-components#readme", "peerDependencies": { "mathjs": "^12.4.2", - "@angular/animations": "^20.0.5", - "@angular/cdk": "^20.0.4", - "@angular/common": "^20.0.5", - "@angular/compiler": "^20.0.5", - "@angular/core": "^20.0.5", - "@angular/elements": "^20.0.5", - "@angular/forms": "^20.0.5", - "@angular/material": "^20.0.4", - "@angular/platform-browser": "^20.0.5", - "@angular/platform-browser-dynamic": "^20.0.5", - "@angular/router": "^20.0.5", + "@angular/animations": ">=20.0.0", + "@angular/cdk": ">=20.0.0", + "@angular/common": ">=20.0.0", + "@angular/compiler": ">=20.0.0", + "@angular/core": ">=20.0.0", + "@angular/elements": ">=20.0.0", + "@angular/forms": ">=20.0.0", + "@angular/material": ">=20.0.0", + "@angular/platform-browser": ">=20.0.0", + "@angular/platform-browser-dynamic": ">=20.0.0", + "@angular/router": ">=20.0.0", "@iqb/responses": "^5.0.0", "@iqbspecs/coding-scheme": "^3.3.1", "@iqbspecs/response": "^1.4.0", @@ -63,7 +63,7 @@ "prosemirror-state": "^1.3.4", "rxjs": "~7.8.0", "docx": "^8.5.0", - "cheerio": "^1.0.0" + "cheerio": "^1.0.0", "zone.js": "~0.15.0" }, "devDependencies": { From d10da6884710e13688036cb8a8ad068d4a40b41c Mon Sep 17 00:00:00 2001 From: jurei733 <67505990+jurei733@users.noreply.github.com> Date: Mon, 16 Mar 2026 08:58:33 +0100 Subject: [PATCH 3/5] Enhance codebook export with provider jobs and progress UI - add provider interface + injection token and export in public API - support provider-loaded units/missings and async job polling with downloads - add progress UI and disable export while jobs run - document provider usage and add component specs - add cheerio/docx dev deps --- package-lock.json | 545 +++++++++++++++--- package.json | 24 +- .../src/lib/codebook-export/README.md | 168 +++++- .../codebook-export.component.html | 46 +- .../codebook-export.component.scss | 46 ++ .../codebook-export.component.spec.ts | 155 +++++ .../codebook-export.component.ts | 354 +++++++++++- .../codebook-export.provider.ts | 37 ++ .../ngx-coding-components/src/public-api.ts | 2 +- 9 files changed, 1239 insertions(+), 138 deletions(-) create mode 100644 projects/ngx-coding-components/src/lib/codebook-export/codebook-export.component.spec.ts create mode 100644 projects/ngx-coding-components/src/lib/codebook-export/codebook-export.provider.ts diff --git a/package-lock.json b/package-lock.json index d7dbeb9..1848a10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,17 +6,17 @@ "": { "name": "coding-components", "dependencies": { - "@angular/animations": "^20.3.17", + "@angular/animations": "^20.3.18", "@angular/cdk": "^20.2.14", - "@angular/common": "^20.3.17", - "@angular/compiler": "^20.3.17", - "@angular/core": "^20.3.17", - "@angular/elements": "^20.3.17", - "@angular/forms": "^20.3.17", + "@angular/common": "^20.3.18", + "@angular/compiler": "^20.3.18", + "@angular/core": "^20.3.18", + "@angular/elements": "^20.3.18", + "@angular/forms": "^20.3.18", "@angular/material": "^20.2.14", - "@angular/platform-browser": "^20.3.17", - "@angular/platform-browser-dynamic": "^20.3.17", - "@angular/router": "^20.3.17", + "@angular/platform-browser": "^20.3.18", + "@angular/platform-browser-dynamic": "^20.3.18", + "@angular/router": "^20.3.18", "@iqb/mathlive": "^0.4.1", "@iqb/responses": "^5.0.0", "@iqbspecs/coding-scheme": "^3.3.1", @@ -37,11 +37,13 @@ "@angular-devkit/core": "^20.3.19", "@angular/build": "^20.3.19", "@angular/cli": "^20.3.19", - "@angular/compiler-cli": "^20.3.17", + "@angular/compiler-cli": "^20.3.18", "@iqb/eslint-config": "^2.2.0", "@types/jasmine": "~4.3.0", "@types/node": "^20.4.4", - "eslint": "^8.57.0", + "cheerio": "^1.0.0", + "docx": "^8.5.0", + "eslint": "^8.57.1", "iqb-dev-components": "^1.4.1", "jasmine-core": "~4.6.0", "karma": "~6.4.0", @@ -517,9 +519,9 @@ } }, "node_modules/@angular/animations": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.17.tgz", - "integrity": "sha512-KvdgFjCTkOD3WVt4gzmJOoX914eey/Efu2Pb/KUM0Bqp1ZoXiFpI48GCd1b6Ks8JlDBeAfgjtpdSUB2aLnMRZQ==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-20.3.18.tgz", + "integrity": "sha512-XFxgSyjfs0SRD2vQVFJljmM4z9nTvUoI8TRqSre/+l8D2FgzD5pG67Aj2BgDgpSFAUkIcI37G48ijK7a3ZZ3WA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -528,7 +530,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "20.3.17" + "@angular/core": "20.3.18" } }, "node_modules/@angular/build": { @@ -697,9 +699,9 @@ } }, "node_modules/@angular/common": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.17.tgz", - "integrity": "sha512-Dqd8f8o9MehszTZIB7o7jrERlwLOSK64gNngK14DCQazz5lpIhAF6hBjx7zjHpa7L9eAYPK1TaxQUXypjzj18Q==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-20.3.18.tgz", + "integrity": "sha512-M62oQbSTRmnGavIVCwimoadg/PDWadgNhactMm9fgH0eM9rx+iWBAYJk4VufO0bwOhysFpRZpJgXlFjOifz/Jw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -708,14 +710,14 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "20.3.17", + "@angular/core": "20.3.18", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/compiler": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.17.tgz", - "integrity": "sha512-cj3x6aFk9xOOxX+qEdeN8T5YbnBNWJ4UMHB/LQoDr7/xCJJGa40IhcOAuJeuF2kGqTwx6MCXnvjO8XOQfHhe9g==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-20.3.18.tgz", + "integrity": "sha512-AaP/LCiDNcYmF135EEozjyR04NRBT38ZfBHQwjhgwiBBTejmvcpHwJaHSkraLpZqZzE4BQqqmgiQ1EJqxEwLVA==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -725,9 +727,9 @@ } }, "node_modules/@angular/compiler-cli": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.17.tgz", - "integrity": "sha512-w5pmO1pXO9tUMgUMWstpDmAWh5s1lJWo+2GI/ByaUEgBZkXd2S92sWoDL+bhy+JSvFzdLGdua6BncHBOX7hEjA==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-20.3.18.tgz", + "integrity": "sha512-zsoEgLgnblmRbi47YwMghKirJ8IBKJ3+I8TxLBRIBrhx+KHFp+6oeDeLyu9H+djdyk88zexVd09wzR/YK73F0g==", "license": "MIT", "dependencies": { "@babel/core": "7.28.3", @@ -747,7 +749,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.3.17", + "@angular/compiler": "20.3.18", "typescript": ">=5.8 <6.0" }, "peerDependenciesMeta": { @@ -757,9 +759,9 @@ } }, "node_modules/@angular/core": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.17.tgz", - "integrity": "sha512-YlQqxMeHI9XJw7I7oM3hYFQd4lQbK37IdlD9ztROIw5FjX6i6lmLU7+X1MQGSRi2r+X9l3IZtl33hRTNvkoUBw==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-20.3.18.tgz", + "integrity": "sha512-B+NQQngd/aDbcfW0zGLis3wTLDeHTeTYMl/mGKQH+HwdPaRCKI1wEtaXaOYVJXkP2FeThocPevB8gLwNlPQUUw==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -768,7 +770,7 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/compiler": "20.3.17", + "@angular/compiler": "20.3.18", "rxjs": "^6.5.3 || ^7.4.0", "zone.js": "~0.15.0" }, @@ -782,9 +784,9 @@ } }, "node_modules/@angular/elements": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/elements/-/elements-20.3.17.tgz", - "integrity": "sha512-6PwdtKlHEJbCK1dCniRBIuvAw5au6kuwiLCSDLwF0OYAeNegdX+tiGnncaIn1FncuyQvAKmwE0lJlMTLx2oIxw==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/elements/-/elements-20.3.18.tgz", + "integrity": "sha512-5UMS+2pbUMfxw9PG60bFBLNx9nSE8agRxxdynvUEbKqBwX9YmILT5F5/8OvmHjORd33GMOIaSRWWEAoi5VtJpg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -793,14 +795,14 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/core": "20.3.17", + "@angular/core": "20.3.18", "rxjs": "^6.5.3 || ^7.4.0" } }, "node_modules/@angular/forms": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.17.tgz", - "integrity": "sha512-iGS6NwzcyJzinbPMapsQtcN0ZJ62vr6hcul+FNa40CaK2ePC04S+C5n+DIphzwnwsFHDBIWuTQRfk/lNYdN1JA==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-20.3.18.tgz", + "integrity": "sha512-x6/99LfxolyZIFUL3Wr0OrtuXHEDwEz/rwx+WzE7NL+n35yO40t3kp0Sn5uMFwI94i91QZJmXHltMpZhrVLuYg==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -809,9 +811,9 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.17", - "@angular/core": "20.3.17", - "@angular/platform-browser": "20.3.17", + "@angular/common": "20.3.18", + "@angular/core": "20.3.18", + "@angular/platform-browser": "20.3.18", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -833,9 +835,9 @@ } }, "node_modules/@angular/platform-browser": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.17.tgz", - "integrity": "sha512-GA8pK+0F2/KGdYn5LMpLBrPTkQUwGjQE8Q+qsivOa150cK3OuD0po5PvYK58l+niGIVvm0wB1xGKTHTOiX/+4A==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-20.3.18.tgz", + "integrity": "sha512-q6s5rEN1yYazpHYp+k4pboXRzMsRB9auzTRBEhyXSGYxqzrnn3qHN0DqgsLC9WAdyhCgnIEMFA8kRT+W277DqQ==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -844,9 +846,9 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/animations": "20.3.17", - "@angular/common": "20.3.17", - "@angular/core": "20.3.17" + "@angular/animations": "20.3.18", + "@angular/common": "20.3.18", + "@angular/core": "20.3.18" }, "peerDependenciesMeta": { "@angular/animations": { @@ -855,9 +857,9 @@ } }, "node_modules/@angular/platform-browser-dynamic": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.17.tgz", - "integrity": "sha512-yTxFuGQ+z0J9khNIhfFZ+kkT7TOFb8kFZKyUz0DxHOmE0q/TEvNZoy3jXOs8xCBFf1+6BY0NqFNlPna+uw36FQ==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-20.3.18.tgz", + "integrity": "sha512-NyTobOGYVzGmPmtI+3lxMzxi0TbLq4SRNQ2ENEJAt6k2JnMmHBm483ppLRAM47nGlDdiraW0IX93EtYYNkiK3g==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -866,16 +868,16 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.17", - "@angular/compiler": "20.3.17", - "@angular/core": "20.3.17", - "@angular/platform-browser": "20.3.17" + "@angular/common": "20.3.18", + "@angular/compiler": "20.3.18", + "@angular/core": "20.3.18", + "@angular/platform-browser": "20.3.18" } }, "node_modules/@angular/router": { - "version": "20.3.17", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.17.tgz", - "integrity": "sha512-p0r0IOJhUcn8WHx4gkSlfwifkkYO5mSDtq4iM5OunZTlSaeSxLb1vTRg2VBgwdzpgAM+eZSMBTTVF/M3pdoELQ==", + "version": "20.3.18", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-20.3.18.tgz", + "integrity": "sha512-3CWejsEYr+ze+ktvWN/qHdyq5WLrj96QZpGYJyxh1pchIcpMPE9MmLpdjf0CUrWYB7g/85u0Geq/xsz72JrGng==", "license": "MIT", "dependencies": { "tslib": "^2.3.0" @@ -884,9 +886,9 @@ "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, "peerDependencies": { - "@angular/common": "20.3.17", - "@angular/core": "20.3.17", - "@angular/platform-browser": "20.3.17", + "@angular/common": "20.3.18", + "@angular/core": "20.3.18", + "@angular/platform-browser": "20.3.18", "rxjs": "^6.5.3 || ^7.4.0" } }, @@ -5674,14 +5676,14 @@ "peer": true }, "node_modules/@schematics/angular": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.2.1.tgz", - "integrity": "sha512-DjrHRMoILhbZ6tc7aNZWuHA1wCm1iU/JN1TxAwNEyIBgyU3Fx8Z5baK4w0TCpOIPt0RLWVgP2L7kka9aXWCUFA==", + "version": "21.2.2", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.2.2.tgz", + "integrity": "sha512-Ywa6HDtX7TRBQZTVMMnxX3Mk7yVnG8KtSFaXWrkx779+q8tqYdBwNwAqbNd4Zatr1GccKaz9xcptHJta5+DTxw==", "license": "MIT", "peer": true, "dependencies": { - "@angular-devkit/core": "21.2.1", - "@angular-devkit/schematics": "21.2.1", + "@angular-devkit/core": "21.2.2", + "@angular-devkit/schematics": "21.2.2", "jsonc-parser": "3.3.1" }, "engines": { @@ -5691,9 +5693,9 @@ } }, "node_modules/@schematics/angular/node_modules/@angular-devkit/core": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.2.1.tgz", - "integrity": "sha512-TpXGjERqVPN8EPt7LdmWAwh0oNQ/6uWFutzGZiXhJy81n1zb1O1XrqhRAmvP1cAo5O+na6IV2JkkCmxL6F8GUg==", + "version": "21.2.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.2.2.tgz", + "integrity": "sha512-xUeKGe4BDQpkz0E6fnAPIJXE0y0nqtap0KhJIBhvN7xi3NenIzTmoi6T9Yv5OOBUdLZbOm4SOel8MhdXiIBpAQ==", "license": "MIT", "peer": true, "dependencies": { @@ -5719,13 +5721,13 @@ } }, "node_modules/@schematics/angular/node_modules/@angular-devkit/schematics": { - "version": "21.2.1", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.2.1.tgz", - "integrity": "sha512-CWoamHaasAHMjHcYqxbj0tMnoXxdGotcAz2SpiuWtH28Lnf5xfbTaJn/lwdMP8Wdh4tgA+uYh2l45A5auCwmkw==", + "version": "21.2.2", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.2.2.tgz", + "integrity": "sha512-CCeyQxGUq+oyGnHd7PfcYIVbj9pRnqjQq0rAojoAqs1BJdtInx9weLBCLy+AjM3NHePeZrnwm+wEVr8apED8kg==", "license": "MIT", "peer": true, "dependencies": { - "@angular-devkit/core": "21.2.1", + "@angular-devkit/core": "21.2.2", "jsonc-parser": "3.3.1", "magic-string": "0.30.21", "ora": "9.3.0", @@ -8025,6 +8027,106 @@ "dev": true, "license": "MIT" }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/chokidar": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", @@ -8956,6 +9058,42 @@ "node": ">=6.0.0" } }, + "node_modules/docx": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/docx/-/docx-8.5.0.tgz", + "integrity": "sha512-4SbcbedPXTciySXiSnNNLuJXpvxFe5nqivbiEHXyL8P/w0wx2uW7YXNjnYgjW0e2e6vy+L/tMISU/oAiXCl57Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "^20.3.1", + "jszip": "^3.10.1", + "nanoid": "^5.0.4", + "xml": "^1.0.1", + "xml-js": "^1.6.8" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/docx/node_modules/nanoid": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz", + "integrity": "sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.js" + }, + "engines": { + "node": "^18 || >=20" + } + }, "node_modules/dom-serialize": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", @@ -9074,6 +9212,33 @@ "node": ">= 0.8" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/engine.io": { "version": "6.6.5", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.5.tgz", @@ -11084,6 +11249,13 @@ "node": ">=0.10.0" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "dev": true, + "license": "MIT" + }, "node_modules/immutable": { "version": "5.1.5", "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz", @@ -12044,6 +12216,59 @@ ], "license": "MIT" }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/jszip/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jszip/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/jszip/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/jszip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/karma": { "version": "6.4.4", "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", @@ -12710,6 +12935,16 @@ } } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -14464,6 +14699,13 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true, + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -14547,6 +14789,85 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parse5-parser-stream/node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, "node_modules/parse5-sax-parser": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-8.0.0.tgz", @@ -14979,9 +15300,9 @@ } }, "node_modules/prosemirror-gapcursor": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.0.tgz", - "integrity": "sha512-z00qvurSdCEWUIulij/isHaqu4uLS8r/Fi61IbjdIPJEonQgggbJsLnstW7Lgdk4zQ68/yr6B6bf7sJXowIgdQ==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.4.1.tgz", + "integrity": "sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==", "license": "MIT", "peer": true, "dependencies": { @@ -15833,8 +16154,8 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz", "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==", + "devOptional": true, "license": "BlueOak-1.0.0", - "optional": true, "engines": { "node": ">=11.0.0" } @@ -16134,6 +16455,13 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true, + "license": "MIT" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -17361,6 +17689,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/undici": { + "version": "7.24.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.1.tgz", + "integrity": "sha512-5xoBibbmnjlcR3jdqtY2Lnx7WbrD/tHlT01TmvqZUFVc9Q1w4+j5hbnapTqbcXITMH1ovjq/W7BkqBilHiVAaA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, "node_modules/undici-types": { "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", @@ -18368,6 +18706,43 @@ "node": ">=0.8.0" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -18579,6 +18954,26 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/xml": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", + "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", + "dev": true, + "license": "MIT" + }, + "node_modules/xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": "^1.2.4" + }, + "bin": { + "xml-js": "bin/cli.js" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index 12c8607..d09a789 100644 --- a/package.json +++ b/package.json @@ -31,17 +31,17 @@ "test:coverage": "npm run test:cc:coverage && npm run test:schemer:coverage" }, "dependencies": { - "@angular/animations": "^20.3.17", + "@angular/animations": "^20.3.18", "@angular/cdk": "^20.2.14", - "@angular/common": "^20.3.17", - "@angular/compiler": "^20.3.17", - "@angular/core": "^20.3.17", - "@angular/elements": "^20.3.17", - "@angular/forms": "^20.3.17", + "@angular/common": "^20.3.18", + "@angular/compiler": "^20.3.18", + "@angular/core": "^20.3.18", + "@angular/elements": "^20.3.18", + "@angular/forms": "^20.3.18", "@angular/material": "^20.2.14", - "@angular/platform-browser": "^20.3.17", - "@angular/platform-browser-dynamic": "^20.3.17", - "@angular/router": "^20.3.17", + "@angular/platform-browser": "^20.3.18", + "@angular/platform-browser-dynamic": "^20.3.18", + "@angular/router": "^20.3.18", "@iqb/mathlive": "^0.4.1", "@iqb/responses": "^5.0.0", "@iqbspecs/coding-scheme": "^3.3.1", @@ -90,11 +90,13 @@ "@angular-devkit/core": "^20.3.19", "@angular/build": "^20.3.19", "@angular/cli": "^20.3.19", - "@angular/compiler-cli": "^20.3.17", + "@angular/compiler-cli": "^20.3.18", "@iqb/eslint-config": "^2.2.0", "@types/jasmine": "~4.3.0", "@types/node": "^20.4.4", - "eslint": "^8.57.0", + "cheerio": "^1.0.0", + "docx": "^8.5.0", + "eslint": "^8.57.1", "iqb-dev-components": "^1.4.1", "jasmine-core": "~4.6.0", "karma": "~6.4.0", diff --git a/projects/ngx-coding-components/src/lib/codebook-export/README.md b/projects/ngx-coding-components/src/lib/codebook-export/README.md index c731600..7cef9a3 100644 --- a/projects/ngx-coding-components/src/lib/codebook-export/README.md +++ b/projects/ngx-coding-components/src/lib/codebook-export/README.md @@ -9,6 +9,7 @@ The codebook export component provides a comprehensive UI for generating and exp - **Missings Profiles**: Select from available missings profiles - **Export Formats**: Export as JSON or DOCX - **Search & Filter**: Quickly find units with built-in search +- **Background Jobs**: Optional async export with progress and downloads ## Installation @@ -65,6 +66,74 @@ export class MyComponent { } ``` +### Provider-Based Example (recommended) + +Use a provider so the component can load data, manage export jobs, and download files. + +```typescript +import { Injectable, Component } from '@angular/core'; +import { map, Observable } from 'rxjs'; +import { + CodebookExportComponent, + CodebookExportProvider, + CodebookExportExecution, + CodebookExportConfig, + UnitSelectionItem, + MissingsProfile, + CODEBOOK_EXPORT_PROVIDER +} from '@iqb/ngx-coding-components'; + +@Injectable() +export class MyCodebookProvider implements CodebookExportProvider { + loadUnits(): Observable{{'loading-units' | translate}}
@@ -42,7 +42,7 @@