@lucca-front/ng 22.0.3 → 22.1.0-rc.1
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/README.md +0 -1
- package/fesm2022/lucca-front-ng-activity-feed.mjs +2 -2
- package/fesm2022/lucca-front-ng-activity-feed.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-approbation-inbox.mjs +1 -1
- package/fesm2022/lucca-front-ng-approbation-inbox.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-bubble-icon.mjs +2 -2
- package/fesm2022/lucca-front-ng-bubble-icon.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-callout.mjs +2 -2
- package/fesm2022/lucca-front-ng-callout.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-api.mjs +0 -9
- package/fesm2022/lucca-front-ng-core-select-api.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-establishment.mjs +9 -32
- package/fesm2022/lucca-front-ng-core-select-establishment.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-job-qualification.mjs +0 -11
- package/fesm2022/lucca-front-ng-core-select-job-qualification.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select-user.mjs +5 -10
- package/fesm2022/lucca-front-ng-core-select-user.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core-select.mjs +29 -65
- package/fesm2022/lucca-front-ng-core-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-core.mjs +5 -1
- package/fesm2022/lucca-front-ng-core.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-data-table.mjs +5 -8
- package/fesm2022/lucca-front-ng-data-table.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-date2.mjs +41 -9
- package/fesm2022/lucca-front-ng-date2.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-dialog.mjs +4 -9
- package/fesm2022/lucca-front-ng-dialog.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-dropdown.mjs +0 -3
- package/fesm2022/lucca-front-ng-dropdown.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-filter-pills.mjs +0 -27
- package/fesm2022/lucca-front-ng-filter-pills.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-form-label.mjs +1 -1
- package/fesm2022/lucca-front-ng-form-label.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-plain-text.mjs +2 -5
- package/fesm2022/lucca-front-ng-forms-rich-text-input-formatters-plain-text.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs +24 -56
- package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-index-table.mjs +2 -2
- package/fesm2022/lucca-front-ng-index-table.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-modal.mjs +2 -7
- package/fesm2022/lucca-front-ng-modal.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-multi-select.mjs +3 -3
- package/fesm2022/lucca-front-ng-multi-select.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-popover2.mjs +2 -2
- package/fesm2022/lucca-front-ng-popover2.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-resource-card.mjs +2 -2
- package/fesm2022/lucca-front-ng-resource-card.mjs.map +1 -1
- package/fesm2022/lucca-front-ng-safe-content.mjs +3 -40
- package/fesm2022/lucca-front-ng-safe-content.mjs.map +1 -1
- package/package.json +4 -4
- package/schematics/collection.json +0 -5
- package/schematics/deprecated-resolver/index.js +4 -1
- package/schematics/lib/angular-component-ast.js +1 -3
- package/schematics/lib/deprecated-mapper.js +10 -2
- package/schematics/lib/html-ast.js +0 -26
- package/src/components/_listbox.scss +6 -12
- package/types/lucca-front-ng-core-select-api.d.ts +0 -11
- package/types/lucca-front-ng-core-select-establishment.d.ts +0 -7
- package/types/lucca-front-ng-core-select-job-qualification.d.ts +0 -8
- package/types/lucca-front-ng-core-select-user.d.ts +0 -6
- package/types/lucca-front-ng-core-select.d.ts +0 -13
- package/types/lucca-front-ng-core.d.ts +3 -1
- package/types/lucca-front-ng-data-table.d.ts +1 -3
- package/types/lucca-front-ng-date2.d.ts +6 -2
- package/types/lucca-front-ng-forms-rich-text-input.d.ts +2 -3
- package/types/lucca-front-ng-safe-content.d.ts +2 -8
- package/schematics/file-upload/index.js +0 -22
- package/schematics/file-upload/migration.js +0 -230
- package/schematics/file-upload/migration.spec.js +0 -56
- package/schematics/file-upload/schema.json +0 -23
|
@@ -262,6 +262,8 @@ declare function ɵeffectWithDeps<const T extends EffectWithDepsInput>(dependenc
|
|
|
262
262
|
*/
|
|
263
263
|
declare function syncInputSignal<T>(signal: ReturnType<typeof input<T>>, setter: (value: T) => void): void;
|
|
264
264
|
|
|
265
|
+
declare function capitalize<T extends string>(str: T): Capitalize<T>;
|
|
266
|
+
|
|
265
267
|
/**
|
|
266
268
|
* Transforms a boolean or a string representation of a boolean into a boolean.
|
|
267
269
|
* @template T The specific boolean literal type to narrow to.
|
|
@@ -389,5 +391,5 @@ interface ILuTree<T> {
|
|
|
389
391
|
disabled?: boolean;
|
|
390
392
|
}
|
|
391
393
|
|
|
392
|
-
export { ALuDateAdapter, ALuOnCloseSubscriber, ALuOnOpenSubscriber, ALuOnScrollBottomSubscriber, ELuDateGranularity, IntlParamsPipe, IntlPluralLabelPipe, LOCALE_PLURAL_RULES, LU_NATIVE_DATE_ADAPTER_OPTIONS, LuNativeDateAdapter, LuStringDateAdapter, LuTypeGuardPipe, PORTAL_CONTEXT, PortalDirective, assertNotNil, defaultBreakpoints, generateId, getIntl, getIntlPluralLabel, getPushPanelInlineSize, getPushPanelViewportMargin, injectMediaMinBreakpoint, intlInputOptions, isNil, isNilOrEmptyString, isNotNil, isNotNilOrEmptyString, isRouterLinkParam, luBooleanAttribute, luDefaultNativeDateAdapterOptions, luNullableBooleanAttribute, luNullableNumberAttribute, luNumberAttribute, luOptionalBooleanAttribute, luOptionalNullableBooleanAttribute, luOptionalNullableNumberAttribute, luOptionalNumberAttribute, syncInputSignal, ɵeffectWithDeps };
|
|
394
|
+
export { ALuDateAdapter, ALuOnCloseSubscriber, ALuOnOpenSubscriber, ALuOnScrollBottomSubscriber, ELuDateGranularity, IntlParamsPipe, IntlPluralLabelPipe, LOCALE_PLURAL_RULES, LU_NATIVE_DATE_ADAPTER_OPTIONS, LuNativeDateAdapter, LuStringDateAdapter, LuTypeGuardPipe, PORTAL_CONTEXT, PortalDirective, assertNotNil, capitalize, defaultBreakpoints, generateId, getIntl, getIntlPluralLabel, getPushPanelInlineSize, getPushPanelViewportMargin, injectMediaMinBreakpoint, intlInputOptions, isNil, isNilOrEmptyString, isNotNil, isNotNilOrEmptyString, isRouterLinkParam, luBooleanAttribute, luDefaultNativeDateAdapterOptions, luNullableBooleanAttribute, luNullableNumberAttribute, luNumberAttribute, luOptionalBooleanAttribute, luOptionalNullableBooleanAttribute, luOptionalNullableNumberAttribute, luOptionalNumberAttribute, syncInputSignal, ɵeffectWithDeps };
|
|
393
395
|
export type { At, Breakpoint, EffectWithDepsInput, EnumValue, ILuDateAdapter, ILuGroup, ILuNativeDateAdapterOptions, ILuOnCloseSubscriber, ILuOnOpenSubscriber, ILuOnScrollBottomSubscriber, ILuTranslation, ILuTree, LuDateGranularity, LuPluralForms, LuTranslation, PortalContent, ResponsiveConfig, ResponsiveProperty, RouterLinkParam };
|
|
@@ -63,7 +63,6 @@ declare class DataTableHeadComponent {
|
|
|
63
63
|
readonly sticky: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
64
64
|
readonly isFirstVisible: _angular_core.WritableSignal<boolean>;
|
|
65
65
|
readonly cols: _angular_core.Signal<readonly DataTableRowCellHeaderComponent[]>;
|
|
66
|
-
tableRef: _lucca_front_ng_data_table.DataTableComponent;
|
|
67
66
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataTableHeadComponent, never>;
|
|
68
67
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTableHeadComponent, "thead[luDataTableHead]", never, { "sticky": { "alias": "sticky"; "required": false; "isSignal": true; }; }, {}, ["cols"], ["*"], true, never>;
|
|
69
68
|
}
|
|
@@ -98,7 +97,6 @@ declare class DataTableComponent implements OnInit {
|
|
|
98
97
|
readonly nested: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
99
98
|
readonly drag: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
100
99
|
readonly noOverflow: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
101
|
-
readonly empty: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
102
100
|
readonly responsive: _angular_core.InputSignal<Partial<Record<"layoutFixedAtMediaMinXXXS" | "layoutFixedAtMediaMinXXS" | "layoutFixedAtMediaMinXS" | "layoutFixedAtMediaMinS" | "layoutFixedAtMediaMinM" | "layoutFixedAtMediaMinL" | "layoutFixedAtMediaMinXL" | "layoutFixedAtMediaMinXXL" | "layoutFixedAtMediaMinXXXL" | "layoutFixedAtContainerMinXXXS" | "layoutFixedAtContainerMinXXS" | "layoutFixedAtContainerMinXS" | "layoutFixedAtContainerMinS" | "layoutFixedAtContainerMinM" | "layoutFixedAtContainerMinL" | "layoutFixedAtContainerMinXL" | "layoutFixedAtContainerMinXXL" | "layoutFixedAtContainerMinXXXL", true>>>;
|
|
103
101
|
readonly verticalAlign: _angular_core.InputSignal<"top" | "middle" | "bottom">;
|
|
104
102
|
readonly rows: _angular_core.Signal<readonly DataTableRowComponent[]>;
|
|
@@ -134,7 +132,7 @@ declare class DataTableComponent implements OnInit {
|
|
|
134
132
|
constructor();
|
|
135
133
|
ngOnInit(): void;
|
|
136
134
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DataTableComponent, never>;
|
|
137
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTableComponent, "lu-data-table", never, { "hover": { "alias": "hover"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "layoutFixed": { "alias": "layoutFixed"; "required": false; "isSignal": true; }; "cellBorder": { "alias": "cellBorder"; "required": false; "isSignal": true; }; "nested": { "alias": "nested"; "required": false; "isSignal": true; }; "drag": { "alias": "drag"; "required": false; "isSignal": true; }; "noOverflow": { "alias": "noOverflow"; "required": false; "isSignal": true; }; "
|
|
135
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DataTableComponent, "lu-data-table", never, { "hover": { "alias": "hover"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "layoutFixed": { "alias": "layoutFixed"; "required": false; "isSignal": true; }; "cellBorder": { "alias": "cellBorder"; "required": false; "isSignal": true; }; "nested": { "alias": "nested"; "required": false; "isSignal": true; }; "drag": { "alias": "drag"; "required": false; "isSignal": true; }; "noOverflow": { "alias": "noOverflow"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "verticalAlign": { "alias": "verticalAlign"; "required": false; "isSignal": true; }; "stickyColsStart": { "alias": "stickyColsStart"; "required": false; "isSignal": true; }; "stickyColsEnd": { "alias": "stickyColsEnd"; "required": false; "isSignal": true; }; }, {}, ["rows", "header"], ["*", "[dataTablePagination]"], true, never>;
|
|
138
136
|
}
|
|
139
137
|
|
|
140
138
|
declare const LU_DATA_TABLE_INSTANCE: InjectionToken<DataTableComponent>;
|
|
@@ -159,6 +159,7 @@ declare class Calendar2Component implements OnInit {
|
|
|
159
159
|
declare function getDateFormat(locale: string, mode?: CalendarMode): string;
|
|
160
160
|
declare function getSeparator(locale: string): string;
|
|
161
161
|
declare function getLocalizedDateFormat(locale: string, period?: CalendarMode, weekPrefix?: string): string;
|
|
162
|
+
declare function humanizeDate(locale: string, date: Date, mode?: CalendarMode, reference?: Date): string | null;
|
|
162
163
|
|
|
163
164
|
/**
|
|
164
165
|
* Available DateComponent Types
|
|
@@ -234,14 +235,17 @@ declare class DateInputComponent extends AbstractDateComponent implements OnInit
|
|
|
234
235
|
readonly disableOverflow: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
235
236
|
readonly hideOverflow: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
236
237
|
readonly widthAuto: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
238
|
+
readonly humanized: _angular_core.InputSignalWithTransform<boolean, boolean | "" | "false" | "true">;
|
|
237
239
|
readonly filterPillDisabled: _angular_core.WritableSignal<boolean>;
|
|
238
240
|
popoverPositions: ConnectionPositionPair[];
|
|
239
241
|
readonly inputFocused: _angular_core.WritableSignal<boolean>;
|
|
242
|
+
readonly panelOpen: _angular_core.WritableSignal<boolean>;
|
|
240
243
|
readonly selectedDate: _angular_core.WritableSignal<Date>;
|
|
241
244
|
readonly initialValue: _angular_core.WritableSignal<Date>;
|
|
242
245
|
readonly dateFromWriteValue: _angular_core.WritableSignal<Date>;
|
|
243
246
|
readonly calendar: _angular_core.Signal<Calendar2Component>;
|
|
244
247
|
readonly inputRef: _angular_core.Signal<ElementRef<HTMLInputElement>>;
|
|
248
|
+
readonly formattedValue: _angular_core.Signal<string>;
|
|
245
249
|
readonly displayValue: _angular_core.Signal<string>;
|
|
246
250
|
readonly userTextInput: _angular_core.WritableSignal<string>;
|
|
247
251
|
combinedGetCellInfo: (date: Date, mode: CalendarMode) => CellStatus;
|
|
@@ -273,7 +277,7 @@ declare class DateInputComponent extends AbstractDateComponent implements OnInit
|
|
|
273
277
|
dateClicked(date: Date, popoverRef: PopoverDirective): void;
|
|
274
278
|
inputBlurred(): void;
|
|
275
279
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<DateInputComponent, never>;
|
|
276
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DateInputComponent, "lu-date-input", never, { "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disableOverflow": { "alias": "disableOverflow"; "required": false; "isSignal": true; }; "hideOverflow": { "alias": "hideOverflow"; "required": false; "isSignal": true; }; "widthAuto": { "alias": "widthAuto"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
280
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DateInputComponent, "lu-date-input", never, { "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "disableOverflow": { "alias": "disableOverflow"; "required": false; "isSignal": true; }; "hideOverflow": { "alias": "hideOverflow"; "required": false; "isSignal": true; }; "widthAuto": { "alias": "widthAuto"; "required": false; "isSignal": true; }; "humanized": { "alias": "humanized"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
277
281
|
}
|
|
278
282
|
|
|
279
283
|
interface CalendarShortcut {
|
|
@@ -349,5 +353,5 @@ declare class DateRangeInputComponent extends AbstractDateComponent implements O
|
|
|
349
353
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<DateRangeInputComponent, "lu-date-range-input", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "widthAuto": { "alias": "widthAuto"; "required": false; "isSignal": true; }; "shortcuts": { "alias": "shortcuts"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
350
354
|
}
|
|
351
355
|
|
|
352
|
-
export { CALENDAR_MODE, Calendar2Component, DATE2_CLEAR_BEHAVIOR, DATE_FORMAT, DATE_FORMAT_CONST, DATE_ISO_FORMAT, DateInputComponent, DateRangeInputComponent, PremadeShortcuts, getDateFormat, getLocalizedDateFormat, getSeparator };
|
|
356
|
+
export { CALENDAR_MODE, Calendar2Component, DATE2_CLEAR_BEHAVIOR, DATE_FORMAT, DATE_FORMAT_CONST, DATE_ISO_FORMAT, DateInputComponent, DateRangeInputComponent, PremadeShortcuts, getDateFormat, getLocalizedDateFormat, getSeparator, humanizeDate };
|
|
353
357
|
export type { CalendarMode, CalendarShortcut, CellStatus, Date2ClearBehavior, DateFormat, DateInputValidatorErrorType, DateRange, DateRangeInput };
|
|
@@ -246,8 +246,6 @@ type SerializedTagNode = Spread<{
|
|
|
246
246
|
tagDescription?: string;
|
|
247
247
|
disabled?: boolean;
|
|
248
248
|
}, SerializedLexicalNode>;
|
|
249
|
-
/** Destroy stale chip components once Lexical has reconciled the DOM. */
|
|
250
|
-
declare function registerTagChipsCleanup(editor: LexicalEditor): () => void;
|
|
251
249
|
declare class TagNode extends DecoratorNode<string> {
|
|
252
250
|
#private;
|
|
253
251
|
setViewContainerRef(vcr: ViewContainerRef): this;
|
|
@@ -267,6 +265,7 @@ declare class TagNode extends DecoratorNode<string> {
|
|
|
267
265
|
decorate(): string;
|
|
268
266
|
createDOM(_config: EditorConfig, editor: LexicalEditor): HTMLElement;
|
|
269
267
|
updateDOM(prevNode: TagNode, _dom: HTMLElement, _config: EditorConfig): boolean;
|
|
268
|
+
remove(preserveEmptyParent?: boolean): void;
|
|
270
269
|
exportDOM(): DOMExportOutput;
|
|
271
270
|
static importDOM(): DOMConversionMap;
|
|
272
271
|
static importJSON(serializedNode: SerializedTagNode): TagNode;
|
|
@@ -313,5 +312,5 @@ declare class RichTextInputToolbarComponent implements RichTextPluginComponent {
|
|
|
313
312
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<RichTextInputToolbarComponent, "lu-rich-text-input-toolbar", never, {}, {}, never, never, true, never>;
|
|
314
313
|
}
|
|
315
314
|
|
|
316
|
-
export { $createTagNode, $isTagNode, ClearFormatComponent, HeadingsComponent, INITIAL_UPDATE_TAG, LinkComponent, ListStyleToolbarComponent, RICH_TEXT_FORMATTER, RICH_TEXT_PLUGIN_COMPONENT, RichTextFormatter, RichTextInputComponent, RichTextInputToolbarComponent, RichTextPluginTagComponent, TagNode, TextStyleComponent, TextStyleToolbarComponent
|
|
315
|
+
export { $createTagNode, $isTagNode, ClearFormatComponent, HeadingsComponent, INITIAL_UPDATE_TAG, LinkComponent, ListStyleToolbarComponent, RICH_TEXT_FORMATTER, RICH_TEXT_PLUGIN_COMPONENT, RichTextFormatter, RichTextInputComponent, RichTextInputToolbarComponent, RichTextPluginTagComponent, TagNode, TextStyleComponent, TextStyleToolbarComponent };
|
|
317
316
|
export type { RichTextPluginComponent, SerializedTagNode, Tag };
|
|
@@ -2,6 +2,7 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { PipeTransform } from '@angular/core';
|
|
3
3
|
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
|
|
4
4
|
import { Config } from 'isomorphic-dompurify';
|
|
5
|
+
export * from '@lucca/prisme/safe-content';
|
|
5
6
|
|
|
6
7
|
type SanitizerConfig = Config & {
|
|
7
8
|
RETURN_DOM_FRAGMENT?: false | undefined;
|
|
@@ -24,11 +25,4 @@ declare class LuSafeContentModule {
|
|
|
24
25
|
static ɵinj: i0.ɵɵInjectorDeclaration<LuSafeContentModule>;
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
#private;
|
|
29
|
-
transform(url: string): SafeHtml;
|
|
30
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<LuSafeExternalSvgPipe, never>;
|
|
31
|
-
static ɵpipe: i0.ɵɵPipeDeclaration<LuSafeExternalSvgPipe, "luSafeExternalSvg", true>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export { LuSafeContentModule, LuSafeExternalSvgPipe, LuSafeHtmlPipe };
|
|
28
|
+
export { LuSafeContentModule, LuSafeHtmlPipe };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const lib_1 = require("../lib");
|
|
4
|
-
const migration_1 = require("./migration");
|
|
5
|
-
// Nx need to see "@angular-devkit/schematics" in order to run this migration correctly (see https://github.com/nrwl/nx/blob/d9fed4b832bf01d1b9a44ae9e486a5e5cd2d2253/packages/nx/src/command-line/migrate/migrate.ts#L1729-L1738)
|
|
6
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
7
|
-
require('@angular-devkit/schematics');
|
|
8
|
-
exports.default = (options) => {
|
|
9
|
-
return async (tree, context) => {
|
|
10
|
-
await lib_1.currentSchematicContext.init(context, options);
|
|
11
|
-
// Templates are reached through their component: rendering a FileEntry or a wrapper needs the
|
|
12
|
-
// matching symbol in the `imports` of the component that owns the template.
|
|
13
|
-
tree.visit((path, entry) => {
|
|
14
|
-
if (path.includes('node_modules') || !entry) {
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
if (path.endsWith('.ts') && !path.endsWith('.d.ts')) {
|
|
18
|
-
(0, lib_1.migrateFile)(path, entry, tree, (content) => (0, migration_1.migrateComponent)(path, content, tree));
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
};
|
|
22
|
-
};
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.migrateComponent = migrateComponent;
|
|
4
|
-
const change_1 = require("@schematics/angular/utility/change");
|
|
5
|
-
const typescript_1 = require("typescript");
|
|
6
|
-
const lib_1 = require("../lib");
|
|
7
|
-
const fileUploadEntrypoint = '@lucca-front/ng/file-upload';
|
|
8
|
-
const wrapperClass = 'fileEntryDisplayWrapper';
|
|
9
|
-
/** Alias given to the migrated entry in the generated `@if` block. */
|
|
10
|
-
const entryAlias = 'fileEntry';
|
|
11
|
-
/** Components whose `size` input has been flipped: `S` became the default, `L` restores the previous rendering. */
|
|
12
|
-
const sizedComponents = ['lu-single-file-upload', 'lu-multi-file-upload', 'lu-file-entry'];
|
|
13
|
-
/** Inputs `lu-single-file-upload` used to forward to the `lu-file-entry` it rendered itself. */
|
|
14
|
-
const fileEntryInputs = ['entry', 'state', 'previewUrl', 'inlineMessageError', 'displayFileName'];
|
|
15
|
-
/** Outputs `lu-single-file-upload` used to forward to the `lu-file-entry` it rendered itself. */
|
|
16
|
-
const fileEntryOutputs = ['deleteFile'];
|
|
17
|
-
function migrateComponent(path, content, tree) {
|
|
18
|
-
const sourceFile = (0, typescript_1.createSourceFile)(path, content, typescript_1.ScriptTarget.ESNext);
|
|
19
|
-
const symbolsToImport = new Set();
|
|
20
|
-
// External templates are rewritten in place, they are not part of the component file.
|
|
21
|
-
(0, lib_1.extractNgTemplatesIncludingHtml)(sourceFile, tree, path)
|
|
22
|
-
.filter((template) => template.filePath !== path)
|
|
23
|
-
.forEach((template) => {
|
|
24
|
-
const migrated = migrateTemplate(template.filePath, template.content, symbolsToImport);
|
|
25
|
-
if (migrated !== template.content) {
|
|
26
|
-
tree.overwrite(template.filePath, migrated);
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
const result = (0, lib_1.updateAngularTemplate)(path, content, (template) => migrateTemplate(path, template, symbolsToImport));
|
|
30
|
-
if (symbolsToImport.size === 0) {
|
|
31
|
-
return result;
|
|
32
|
-
}
|
|
33
|
-
// Imports are inserted one symbol at a time: every insertion shifts the offsets the next one relies on.
|
|
34
|
-
tree.overwrite(path, result);
|
|
35
|
-
symbolsToImport.forEach((symbol) => {
|
|
36
|
-
const updatedSourceFile = (0, typescript_1.createSourceFile)(path, tree.readText(path), typescript_1.ScriptTarget.ESNext);
|
|
37
|
-
const recorder = tree.beginUpdate(path);
|
|
38
|
-
(0, change_1.applyToUpdateRecorder)(recorder, [(0, lib_1.insertTSImportIfNeeded)(updatedSourceFile, path, symbol, fileUploadEntrypoint), (0, lib_1.insertAngularImportIfNeeded)(updatedSourceFile, path, symbol)]);
|
|
39
|
-
tree.commitUpdate(recorder);
|
|
40
|
-
});
|
|
41
|
-
return tree.readText(path);
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Rules are applied in this order on purpose:
|
|
45
|
-
* 1. sizes are normalized first, so that splitting a `lu-single-file-upload` reads an already migrated size;
|
|
46
|
-
* 2. the split then emits its own `lu-file-entry-wrapper`, which the class rule must not visit again.
|
|
47
|
-
*/
|
|
48
|
-
function migrateTemplate(path, template, symbolsToImport) {
|
|
49
|
-
let result = migrateSize(path, template);
|
|
50
|
-
result = migrateFileEntryRendering(path, result, symbolsToImport);
|
|
51
|
-
return migrateWrapperClass(path, result, symbolsToImport);
|
|
52
|
-
}
|
|
53
|
-
function migrateSize(path, template) {
|
|
54
|
-
return (0, lib_1.updateContent)(template, (updates) => {
|
|
55
|
-
const htmlAst = new lib_1.HtmlAst(template);
|
|
56
|
-
sizedComponents.forEach((component) => {
|
|
57
|
-
htmlAst.visitElements(component, (element) => {
|
|
58
|
-
const boundSize = element.inputs.find((input) => input.name === 'size');
|
|
59
|
-
if (boundSize) {
|
|
60
|
-
const source = boundSize.value instanceof lib_1.currentSchematicContext.angularCompiler.ASTWithSource ? boundSize.value.source ?? '' : '';
|
|
61
|
-
switch (source.trim()) {
|
|
62
|
-
case `'S'`:
|
|
63
|
-
case `"S"`:
|
|
64
|
-
updates.push((0, lib_1.removeAttributeUpdate)(template, boundSize));
|
|
65
|
-
lib_1.currentSchematicContext.logSuccess(`Removing redundant [size] on <${component}> in ${path}`);
|
|
66
|
-
break;
|
|
67
|
-
case 'null':
|
|
68
|
-
updates.push({
|
|
69
|
-
position: boundSize.value.sourceSpan.start,
|
|
70
|
-
oldContent: source,
|
|
71
|
-
newContent: source.replace('null', `'L'`),
|
|
72
|
-
});
|
|
73
|
-
lib_1.currentSchematicContext.logSuccess(`Setting [size] to 'L' on <${component}> in ${path}`);
|
|
74
|
-
break;
|
|
75
|
-
default:
|
|
76
|
-
lib_1.currentSchematicContext.warn(`${path}: [size] of <${component}> is bound to an expression, migrate it manually ('S' is now the default value, 'L' is the previous one).`);
|
|
77
|
-
}
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
const size = element.attributes.find((attribute) => attribute.name === 'size');
|
|
81
|
-
if (!size) {
|
|
82
|
-
updates.push((0, lib_1.addAttributeUpdate)(element, 'size', 'L'));
|
|
83
|
-
lib_1.currentSchematicContext.logSuccess(`Adding size="L" on <${component}> in ${path}`);
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (size.value === 'S') {
|
|
87
|
-
updates.push((0, lib_1.removeAttributeUpdate)(template, size));
|
|
88
|
-
lib_1.currentSchematicContext.logSuccess(`Removing redundant size="S" on <${component}> in ${path}`);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
lib_1.currentSchematicContext.warn(`${path}: size="${size.value}" of <${component}> is not a known value, migrate it manually ('S' is now the default value, 'L' is the previous one).`);
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* `lu-single-file-upload` no longer renders the `FileEntry` it receives: the parent now displays it itself,
|
|
98
|
-
* through a `lu-file-entry` wrapped in a `lu-file-entry-wrapper`.
|
|
99
|
-
*/
|
|
100
|
-
function migrateFileEntryRendering(path, template, symbolsToImport) {
|
|
101
|
-
return (0, lib_1.updateContent)(template, (updates) => {
|
|
102
|
-
const htmlAst = new lib_1.HtmlAst(template);
|
|
103
|
-
htmlAst.visitElements('lu-single-file-upload', (element) => {
|
|
104
|
-
const entry = element.inputs.find((input) => input.name === 'entry');
|
|
105
|
-
if (!entry) {
|
|
106
|
-
if (element.attributes.some((attribute) => attribute.name === 'entry')) {
|
|
107
|
-
lib_1.currentSchematicContext.warn(`${path}: <lu-single-file-upload> has a static entry attribute, migrate it manually.`);
|
|
108
|
-
}
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
// A size left bound to an expression by the size rule cannot be turned into the `media` of the file
|
|
112
|
-
// entry, which is what the file upload used to derive from it.
|
|
113
|
-
if (element.inputs.some((input) => input.name === 'size') && !hasSizeL(element)) {
|
|
114
|
-
lib_1.currentSchematicContext.warn(`${path}: <lu-single-file-upload [entry]> has a [size] bound to an expression, migrate it manually.`);
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const openingTag = template.slice(element.startSourceSpan.start.offset, element.startSourceSpan.end.offset);
|
|
118
|
-
if (/\s\*[\w-]+/.test(openingTag)) {
|
|
119
|
-
lib_1.currentSchematicContext.warn(`${path}: <lu-single-file-upload [entry]> carries a structural directive, migrate it manually.`);
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
const entryExpression = entry.value instanceof lib_1.currentSchematicContext.angularCompiler.ASTWithSource ? (entry.value.source ?? '').trim() : '';
|
|
123
|
-
if (!entryExpression) {
|
|
124
|
-
lib_1.currentSchematicContext.warn(`${path}: could not read the [entry] expression of <lu-single-file-upload>, migrate it manually.`);
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
updates.push(buildFileEntryRendering(template, element, entryExpression));
|
|
128
|
-
symbolsToImport.add('FileEntryComponent');
|
|
129
|
-
symbolsToImport.add('FileEntryWrapperComponent');
|
|
130
|
-
lib_1.currentSchematicContext.logSuccess(`Extracting the FileEntry of <lu-single-file-upload> in ${path}`);
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
function buildFileEntryRendering(template, element, entryExpression) {
|
|
135
|
-
const start = element.sourceSpan.start.offset;
|
|
136
|
-
const end = (element.endSourceSpan ?? element.sourceSpan).end.offset;
|
|
137
|
-
const movedAttributes = [
|
|
138
|
-
...element.inputs.filter((input) => fileEntryInputs.includes(input.name)),
|
|
139
|
-
...element.attributes.filter((attribute) => fileEntryInputs.includes(attribute.name)),
|
|
140
|
-
...element.outputs.filter((output) => fileEntryOutputs.includes(output.name)),
|
|
141
|
-
];
|
|
142
|
-
// `lu-single-file-upload` used to render its entry as a media only in its large variant, always at size L.
|
|
143
|
-
const isLarge = hasSizeL(element);
|
|
144
|
-
const hasStructure = [...element.attributes, ...element.inputs].some((attribute) => attribute.name === 'structure');
|
|
145
|
-
const fileEntryAttributes = [
|
|
146
|
-
`[entry]="${entryAlias}"`,
|
|
147
|
-
'size="L"',
|
|
148
|
-
isLarge ? 'media' : '',
|
|
149
|
-
hasStructure ? 'structure' : '',
|
|
150
|
-
...movedAttributes.filter((attribute) => attribute.name !== 'entry').map((attribute) => template.slice(attribute.sourceSpan.start.offset, attribute.sourceSpan.end.offset)),
|
|
151
|
-
].filter(Boolean);
|
|
152
|
-
// The remaining file upload keeps everything the file entry did not take, formatting included.
|
|
153
|
-
const fileUpload = (0, lib_1.applyUpdates)(template.slice(start, end), movedAttributes.map((attribute) => {
|
|
154
|
-
const update = (0, lib_1.removeAttributeUpdate)(template, attribute);
|
|
155
|
-
return { ...update, position: update.position - start };
|
|
156
|
-
}));
|
|
157
|
-
const indent = getIndent(template, start);
|
|
158
|
-
const unit = indent.includes(' ') && !indent.includes('\t') ? ' ' : '\t';
|
|
159
|
-
return {
|
|
160
|
-
position: start,
|
|
161
|
-
oldContent: template.slice(start, end),
|
|
162
|
-
newContent: [
|
|
163
|
-
`@if (${entryExpression}; as ${entryAlias}) {`,
|
|
164
|
-
`${indent}${unit}<lu-file-entry-wrapper>`,
|
|
165
|
-
`${indent}${unit}${unit}<lu-file-entry ${fileEntryAttributes.join(' ')} />`,
|
|
166
|
-
`${indent}${unit}</lu-file-entry-wrapper>`,
|
|
167
|
-
`${indent}} @else {`,
|
|
168
|
-
`${indent}${unit}${fileUpload}`,
|
|
169
|
-
`${indent}}`,
|
|
170
|
-
].join('\n'),
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
/** The `fileEntryDisplayWrapper` CSS class is now carried by the `lu-file-entry-wrapper` component. */
|
|
174
|
-
function migrateWrapperClass(path, template, symbolsToImport) {
|
|
175
|
-
return (0, lib_1.updateContent)(template, (updates) => {
|
|
176
|
-
const htmlAst = new lib_1.HtmlAst(template);
|
|
177
|
-
htmlAst.visitElements(/.*/, (element) => {
|
|
178
|
-
const boundClass = element.inputs.find((input) => input.name === 'class' || input.name === `class.${wrapperClass}` || input.name === 'ngClass');
|
|
179
|
-
if (boundClass && template.slice(boundClass.sourceSpan.start.offset, boundClass.sourceSpan.end.offset).includes(wrapperClass)) {
|
|
180
|
-
lib_1.currentSchematicContext.warn(`${path}: .${wrapperClass} is applied through a binding on <${element.name}>, migrate it manually.`);
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
const classAttribute = element.attributes.find((attribute) => attribute.name === 'class');
|
|
184
|
-
const classes = classAttribute?.value.split(/\s+/).filter(Boolean) ?? [];
|
|
185
|
-
if (!classes.includes(wrapperClass) || !classAttribute) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
updates.push({
|
|
189
|
-
position: element.startSourceSpan.start.offset + '<'.length,
|
|
190
|
-
oldContent: element.name,
|
|
191
|
-
newContent: 'lu-file-entry-wrapper',
|
|
192
|
-
});
|
|
193
|
-
if (element.endSourceSpan && !element.isSelfClosing) {
|
|
194
|
-
updates.push({
|
|
195
|
-
position: element.endSourceSpan.start.offset + '</'.length,
|
|
196
|
-
oldContent: element.name,
|
|
197
|
-
newContent: 'lu-file-entry-wrapper',
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
|
-
const remainingClasses = classes.filter((className) => className !== wrapperClass);
|
|
201
|
-
if (remainingClasses.length === 0) {
|
|
202
|
-
updates.push((0, lib_1.removeAttributeUpdate)(template, classAttribute));
|
|
203
|
-
}
|
|
204
|
-
else if (classAttribute.valueSpan) {
|
|
205
|
-
updates.push({
|
|
206
|
-
position: classAttribute.valueSpan.start.offset,
|
|
207
|
-
oldContent: classAttribute.value,
|
|
208
|
-
newContent: remainingClasses.join(' '),
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
symbolsToImport.add('FileEntryWrapperComponent');
|
|
212
|
-
lib_1.currentSchematicContext.logSuccess(`Replacing .${wrapperClass} with <lu-file-entry-wrapper> in ${path}`);
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
function hasSizeL(element) {
|
|
217
|
-
if (element.attributes.some((attribute) => attribute.name === 'size' && attribute.value === 'L')) {
|
|
218
|
-
return true;
|
|
219
|
-
}
|
|
220
|
-
return element.inputs.some((input) => {
|
|
221
|
-
const source = input.value instanceof lib_1.currentSchematicContext.angularCompiler.ASTWithSource ? input.value.source ?? '' : '';
|
|
222
|
-
return input.name === 'size' && /^['"]L['"]$/.test(source.trim());
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
/** Whitespace preceding the element on its own line, used to indent the generated block. */
|
|
226
|
-
function getIndent(template, position) {
|
|
227
|
-
const lineStart = template.lastIndexOf('\n', position - 1) + 1;
|
|
228
|
-
const prefix = template.slice(lineStart, position);
|
|
229
|
-
return /^\s*$/.test(prefix) ? prefix : '';
|
|
230
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
const path = __importStar(require("path"));
|
|
37
|
-
const lib_1 = require("../lib");
|
|
38
|
-
const collectionPath = path.normalize(path.join(__dirname, '..', 'collection.json'));
|
|
39
|
-
const testsRoot = path.join(__dirname, 'tests');
|
|
40
|
-
describe('file-upload Migration', () => {
|
|
41
|
-
it('should handle basic case files', async () => {
|
|
42
|
-
// Arrange
|
|
43
|
-
const tree = (0, lib_1.createTreeFromFolder)(path.join(testsRoot, 'input'));
|
|
44
|
-
const expectedTree = (0, lib_1.createTreeFromFolder)(path.join(testsRoot, 'output'));
|
|
45
|
-
// Act
|
|
46
|
-
try {
|
|
47
|
-
await (0, lib_1.runSchematic)('collection', collectionPath, 'file-upload', { skipInstall: true }, tree);
|
|
48
|
-
}
|
|
49
|
-
catch (error) {
|
|
50
|
-
// eslint-disable-next-line no-console
|
|
51
|
-
console.log(error);
|
|
52
|
-
}
|
|
53
|
-
// Assert
|
|
54
|
-
(0, lib_1.expectTree)(tree).toMatchTree(expectedTree);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema",
|
|
3
|
-
"$id": "LuccaFrontFileUpload",
|
|
4
|
-
"title": "Lucca Front File Upload Schema",
|
|
5
|
-
"type": "object",
|
|
6
|
-
"properties": {
|
|
7
|
-
"dryRun": {
|
|
8
|
-
"type": "boolean",
|
|
9
|
-
"description": "Run through the migration without making any changes.",
|
|
10
|
-
"default": false
|
|
11
|
-
},
|
|
12
|
-
"skipInstall": {
|
|
13
|
-
"type": "boolean",
|
|
14
|
-
"description": "Skip installing dependencies.",
|
|
15
|
-
"default": false
|
|
16
|
-
},
|
|
17
|
-
"verbose": {
|
|
18
|
-
"type": "boolean",
|
|
19
|
-
"description": "Enable verbose logging.",
|
|
20
|
-
"default": false
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|