@lucca-front/ng 21.3.0 → 21.3.1-rc.2

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.
Files changed (29) hide show
  1. package/fesm2022/lucca-front-ng-box.mjs +41 -4
  2. package/fesm2022/lucca-front-ng-box.mjs.map +1 -1
  3. package/fesm2022/lucca-front-ng-color.mjs +2 -2
  4. package/fesm2022/lucca-front-ng-color.mjs.map +1 -1
  5. package/fesm2022/lucca-front-ng-core-select-department.mjs +18 -11
  6. package/fesm2022/lucca-front-ng-core-select-department.mjs.map +1 -1
  7. package/fesm2022/lucca-front-ng-data-table.mjs +2 -2
  8. package/fesm2022/lucca-front-ng-data-table.mjs.map +1 -1
  9. package/fesm2022/lucca-front-ng-form-header.mjs +2 -2
  10. package/fesm2022/lucca-front-ng-form-header.mjs.map +1 -1
  11. package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs +15 -5
  12. package/fesm2022/lucca-front-ng-forms-rich-text-input.mjs.map +1 -1
  13. package/fesm2022/lucca-front-ng-forms.mjs +2 -2
  14. package/fesm2022/lucca-front-ng-forms.mjs.map +1 -1
  15. package/fesm2022/lucca-front-ng-skeleton.mjs +2 -2
  16. package/fesm2022/lucca-front-ng-skeleton.mjs.map +1 -1
  17. package/fesm2022/lucca-front-ng-software-icon.mjs +1 -0
  18. package/fesm2022/lucca-front-ng-software-icon.mjs.map +1 -1
  19. package/fesm2022/lucca-front-ng-time.mjs +6 -4
  20. package/fesm2022/lucca-front-ng-time.mjs.map +1 -1
  21. package/package.json +4 -4
  22. package/schematics/lib/deprecated-mapper.js +1 -1
  23. package/schematics/lu-grid/migration.js +31 -58
  24. package/schematics/lu-grid/migration.utils.js +60 -0
  25. package/types/lucca-front-ng-box.d.ts +6 -1
  26. package/types/lucca-front-ng-core-select-department.d.ts +10 -9
  27. package/types/lucca-front-ng-form-header.d.ts +1 -1
  28. package/types/lucca-front-ng-software-icon.d.ts +2 -2
  29. package/types/lucca-front-ng-time.d.ts +1 -0
@@ -3,57 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.migrateComponent = migrateComponent;
4
4
  const change_1 = require("@schematics/angular/utility/change");
5
5
  const lib_1 = require("../lib");
6
- // --- CSS custom properties helpers ---
7
- function parseCssCustomProperties(style) {
8
- const result = {};
9
- style.split(';').map((p) => p.trim()).filter(Boolean).forEach((part) => {
10
- const colonIdx = part.indexOf(':');
11
- if (colonIdx === -1) {
12
- return;
13
- }
14
- const prop = part.substring(0, colonIdx).trim();
15
- const value = part.substring(colonIdx + 1).trim();
16
- result[prop] = value;
17
- });
18
- return result;
19
- }
20
- // CSS custom properties that map directly to GridColumnComponent inputs
21
- const GRID_COLUMN_DIRECT_PROPS = {
22
- '--grid-colspan': 'colspan',
23
- '--grid-rowspan': 'rowspan',
24
- '--grid-column': 'column',
25
- '--grid-row': 'row',
26
- '--grid-justify': 'justify',
27
- '--grid-align': 'align',
28
- };
29
- // Prefix for responsive CSS custom properties
30
- const RESPONSIVE_PREFIX = '--grid-';
31
- function extractGridColumnInputs(style) {
32
- const cssProps = parseCssCustomProperties(style);
33
- const inputs = {};
34
- const responsive = {};
35
- const remaining = [];
36
- for (const [prop, value] of Object.entries(cssProps)) {
37
- if (GRID_COLUMN_DIRECT_PROPS[prop]) {
38
- inputs[GRID_COLUMN_DIRECT_PROPS[prop]] = value;
39
- }
40
- else if (prop.startsWith(RESPONSIVE_PREFIX) && prop.includes('AtMedia')) {
41
- // e.g. --grid-colspanAtMediaMinXS → colspanAtMediaMinXS
42
- const key = prop.substring(RESPONSIVE_PREFIX.length);
43
- responsive[key] = value;
44
- }
45
- else if (prop.startsWith('--grid-')) {
46
- // Unknown grid property — drop it (it was grid-specific)
47
- }
48
- else {
49
- remaining.push(`${prop}: ${value}`);
50
- }
51
- }
52
- if (Object.keys(responsive).length > 0) {
53
- inputs.responsive = responsive;
54
- }
55
- return { inputs, remainingStyle: remaining.join('; ') };
56
- }
6
+ const migration_utils_1 = require("./migration.utils");
57
7
  // --- Main migration ---
58
8
  function migrateComponent(sourceFile, path, tree) {
59
9
  const htmlGrids = findHTMLGrids(sourceFile, path, tree);
@@ -84,7 +34,7 @@ function migrateComponent(sourceFile, path, tree) {
84
34
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
35
  function migrateGridNode(grid, templateUpdate) {
86
36
  const { node, nodeOffset, inputs } = grid;
87
- const divLength = node.name.length; // 'div'
37
+ const divLength = node.name.length;
88
38
  const classesNode = node.attributes.find((attr) => attr.name === 'class');
89
39
  const styleNode = node.attributes.find((attr) => attr.name === 'style');
90
40
  // Build inputs string (everything that comes after the element name)
@@ -124,7 +74,7 @@ function migrateGridNode(grid, templateUpdate) {
124
74
  }
125
75
  // Modify style attribute — remove --grid-columns, keep the rest
126
76
  if (styleNode && styleNode.keySpan) {
127
- const cssProps = parseCssCustomProperties(styleNode.value);
77
+ const cssProps = (0, migration_utils_1.parseCssCustomProperties)(styleNode.value);
128
78
  const remaining = Object.entries(cssProps)
129
79
  .filter(([key]) => key !== '--grid-columns')
130
80
  .map(([key, val]) => `${key}: ${val}`)
@@ -138,7 +88,7 @@ function migrateGridNode(grid, templateUpdate) {
138
88
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
139
89
  function migrateGridColumnNode(col, templateUpdate) {
140
90
  const { node, nodeOffset, inputs, remainingStyle, extraClasses } = col;
141
- const divLength = node.name.length; // 'div'
91
+ const divLength = node.name.length;
142
92
  const classesNode = node.attributes.find((attr) => attr.name === 'class');
143
93
  const styleNode = node.attributes.find((attr) => attr.name === 'style');
144
94
  // Build inputs string
@@ -199,21 +149,33 @@ function migrateGridColumnNode(col, templateUpdate) {
199
149
  }
200
150
  }
201
151
  // --- Finders ---
152
+ function gridHasNonNeutralColumnChildren(node) {
153
+ return node.children.some((child) => {
154
+ if (!(0, lib_1.isInterestingNode)(child) || (0, migration_utils_1.isNeutralElement)(child.name)) {
155
+ return false;
156
+ }
157
+ const childClasses = child.attributes.find((attr) => attr.name === 'class')?.value;
158
+ return !!childClasses?.match(/(^|\s)grid-column(\s|$)/);
159
+ });
160
+ }
202
161
  function findHTMLGrids(sourceFile, basePath, tree) {
203
162
  const results = [];
204
163
  const ngTemplates = (0, lib_1.extractNgTemplatesIncludingHtml)(sourceFile, tree, basePath);
205
164
  ngTemplates.forEach((template) => {
206
165
  const htmlAst = new lib_1.HtmlAst(template.content);
207
166
  htmlAst.visitNodes((node) => {
208
- if (!(0, lib_1.isInterestingNode)(node) || node.name !== 'div') {
167
+ if (!(0, lib_1.isInterestingNode)(node) || !(0, migration_utils_1.isNeutralElement)(node.name)) {
209
168
  return;
210
169
  }
211
170
  const classes = node.attributes.find((attr) => attr.name === 'class')?.value;
212
171
  if (!classes?.match(/(^|\s)grid(\s|$)/)) {
213
172
  return;
214
173
  }
174
+ if (gridHasNonNeutralColumnChildren(node)) {
175
+ return;
176
+ }
215
177
  const styleAttr = node.attributes.find((attr) => attr.name === 'style')?.value || '';
216
- const cssProps = parseCssCustomProperties(styleAttr);
178
+ const cssProps = (0, migration_utils_1.parseCssCustomProperties)(styleAttr);
217
179
  const classParts = classes.split(' ');
218
180
  const extraClasses = classParts.filter((c) => c !== 'grid' && c !== 'mod-auto' && c !== 'mod-form').join(' ');
219
181
  const inputs = {
@@ -237,7 +199,7 @@ function findHTMLGridColumns(sourceFile, basePath, tree) {
237
199
  const ngTemplates = (0, lib_1.extractNgTemplatesIncludingHtml)(sourceFile, tree, basePath);
238
200
  ngTemplates.forEach((template) => {
239
201
  const htmlAst = new lib_1.HtmlAst(template.content);
240
- htmlAst.visitNodes((node) => {
202
+ htmlAst.visitNodes((node, parent) => {
241
203
  if (!(0, lib_1.isInterestingNode)(node)) {
242
204
  return;
243
205
  }
@@ -245,8 +207,19 @@ function findHTMLGridColumns(sourceFile, basePath, tree) {
245
207
  if (!classes?.match(/(^|\s)grid-column(\s|$)/)) {
246
208
  return;
247
209
  }
210
+ // Only migrate grid-column if its parent grid container is also being migrated
211
+ if (!(0, lib_1.isInterestingNode)(parent) || !(0, migration_utils_1.isNeutralElement)(parent.name)) {
212
+ return;
213
+ }
214
+ const parentClasses = parent.attributes.find((attr) => attr.name === 'class')?.value;
215
+ if (!parentClasses?.match(/(^|\s)grid(\s|$)/)) {
216
+ return;
217
+ }
218
+ if (gridHasNonNeutralColumnChildren(parent)) {
219
+ return;
220
+ }
248
221
  const styleAttr = node.attributes.find((attr) => attr.name === 'style')?.value || '';
249
- const { inputs, remainingStyle } = extractGridColumnInputs(styleAttr);
222
+ const { inputs, remainingStyle } = (0, migration_utils_1.extractGridColumnInputs)(styleAttr);
250
223
  const classParts = classes.split(' ');
251
224
  const extraClasses = classParts.filter((c) => c !== 'grid-column').join(' ');
252
225
  results.push({
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseCssCustomProperties = parseCssCustomProperties;
4
+ exports.extractGridColumnInputs = extractGridColumnInputs;
5
+ exports.isNeutralElement = isNeutralElement;
6
+ // --- CSS custom properties helpers ---
7
+ function parseCssCustomProperties(style) {
8
+ const result = {};
9
+ style.split(';').map((p) => p.trim()).filter(Boolean).forEach((part) => {
10
+ const colonIdx = part.indexOf(':');
11
+ if (colonIdx === -1) {
12
+ return;
13
+ }
14
+ const prop = part.substring(0, colonIdx).trim();
15
+ const value = part.substring(colonIdx + 1).trim();
16
+ result[prop] = value;
17
+ });
18
+ return result;
19
+ }
20
+ // CSS custom properties that map directly to GridColumnComponent inputs
21
+ const GRID_COLUMN_DIRECT_PROPS = {
22
+ '--grid-colspan': 'colspan',
23
+ '--grid-rowspan': 'rowspan',
24
+ '--grid-column': 'column',
25
+ '--grid-row': 'row',
26
+ '--grid-justify': 'justify',
27
+ '--grid-align': 'align',
28
+ };
29
+ // Prefix for responsive CSS custom properties
30
+ const RESPONSIVE_PREFIX = '--grid-';
31
+ function extractGridColumnInputs(style) {
32
+ const cssProps = parseCssCustomProperties(style);
33
+ const inputs = {};
34
+ const responsive = {};
35
+ const remaining = [];
36
+ for (const [prop, value] of Object.entries(cssProps)) {
37
+ if (GRID_COLUMN_DIRECT_PROPS[prop]) {
38
+ inputs[GRID_COLUMN_DIRECT_PROPS[prop]] = value;
39
+ }
40
+ else if (prop.startsWith(RESPONSIVE_PREFIX) && prop.includes('AtMedia')) {
41
+ // e.g. --grid-colspanAtMediaMinXS → colspanAtMediaMinXS
42
+ const key = prop.substring(RESPONSIVE_PREFIX.length);
43
+ responsive[key] = value;
44
+ }
45
+ else if (prop.startsWith('--grid-')) {
46
+ // Unknown grid property — drop it (it was grid-specific)
47
+ }
48
+ else {
49
+ remaining.push(`${prop}: ${value}`);
50
+ }
51
+ }
52
+ if (Object.keys(responsive).length > 0) {
53
+ inputs.responsive = responsive;
54
+ }
55
+ return { inputs, remainingStyle: remaining.join('; ') };
56
+ }
57
+ const NEUTRAL_HTML_ELEMENTS = ['div', 'span', 'section'];
58
+ function isNeutralElement(name) {
59
+ return NEUTRAL_HTML_ELEMENTS.includes(name);
60
+ }
@@ -1,13 +1,18 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
 
3
+ interface LuBoxLabel {
4
+ close: string;
5
+ }
6
+
3
7
  declare class BoxComponent {
8
+ readonly intl: _angular_core.InputSignalWithTransform<LuBoxLabel, Partial<LuBoxLabel>>;
4
9
  readonly toggle: _angular_core.InputSignalWithTransform<boolean, unknown>;
5
10
  readonly neutral: _angular_core.InputSignalWithTransform<boolean, unknown>;
6
11
  readonly killable: _angular_core.InputSignalWithTransform<boolean, unknown>;
7
12
  readonly withArrow: _angular_core.InputSignalWithTransform<boolean, unknown>;
8
13
  readonly killed: _angular_core.OutputEmitterRef<void>;
9
14
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<BoxComponent, never>;
10
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<BoxComponent, "lu-box", never, { "toggle": { "alias": "toggle"; "required": false; "isSignal": true; }; "neutral": { "alias": "neutral"; "required": false; "isSignal": true; }; "killable": { "alias": "killable"; "required": false; "isSignal": true; }; "withArrow": { "alias": "withArrow"; "required": false; "isSignal": true; }; }, { "killed": "killed"; }, never, ["*"], true, never>;
15
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<BoxComponent, "lu-box", never, { "intl": { "alias": "intl"; "required": false; "isSignal": true; }; "toggle": { "alias": "toggle"; "required": false; "isSignal": true; }; "neutral": { "alias": "neutral"; "required": false; "isSignal": true; }; "killable": { "alias": "killable"; "required": false; "isSignal": true; }; "withArrow": { "alias": "withArrow"; "required": false; "isSignal": true; }; }, { "killed": "killed"; }, never, ["*"], true, never>;
11
16
  }
12
17
 
13
18
  export { BoxComponent };
@@ -19,12 +19,13 @@ declare class NoopTreeSelectDirective<T extends TreeNode<any>, V> implements Tre
19
19
 
20
20
  declare class LuCoreSelectDepartmentsDirective<T extends ILuDepartment = ILuDepartment> extends ALuCoreSelectApiDirective<TreeNode<T>> implements OnInit, CoreSelectApiTotalCountProvider {
21
21
  protected httpClient: HttpClient;
22
- url: _angular_core.InputSignal<string>;
23
- filters: _angular_core.InputSignal<Record<string, string | number | boolean>>;
24
- operationIds: _angular_core.InputSignal<readonly number[]>;
25
- uniqueOperationIds: _angular_core.InputSignal<readonly number[]>;
26
- appInstanceId: _angular_core.InputSignal<number>;
27
- searchDelimiter: _angular_core.InputSignal<string>;
22
+ readonly url: _angular_core.InputSignal<string>;
23
+ readonly countUrl: _angular_core.InputSignal<string>;
24
+ readonly filters: _angular_core.InputSignal<Record<string, string | number | boolean>>;
25
+ readonly operationIds: _angular_core.InputSignal<readonly number[]>;
26
+ readonly uniqueOperationIds: _angular_core.InputSignal<readonly number[]>;
27
+ readonly appInstanceId: _angular_core.InputSignal<number>;
28
+ readonly searchDelimiter: _angular_core.InputSignal<string>;
28
29
  ngOnInit(): void;
29
30
  protected buildOptions(): Observable<TreeNode<T>[]>;
30
31
  protected getOptionsPage(params: Record<string, string | number | boolean> | null, page: number): Observable<{
@@ -33,12 +34,12 @@ declare class LuCoreSelectDepartmentsDirective<T extends ILuDepartment = ILuDepa
33
34
  }>;
34
35
  protected getOptions(params: Record<string, string | number | boolean> | null): Observable<TreeNode<T>[]>;
35
36
  trim(options: TreeNode<T>[], clue: string): TreeNode<T>[];
36
- protected params$: Observable<Record<string, string | number | boolean>>;
37
- totalCount$: Observable<number>;
37
+ protected readonly params$: Observable<Record<string, string | number | boolean>>;
38
+ readonly totalCount$: Observable<number>;
38
39
  protected flattenTree(branch: TreeNode<T>): T[];
39
40
  protected optionKey: (option: TreeNode<T> | T) => number;
40
41
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<LuCoreSelectDepartmentsDirective<any>, never>;
41
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<LuCoreSelectDepartmentsDirective<any>, "lu-simple-select[departments],lu-multi-select[departments]", ["luDepartments"], { "url": { "alias": "url"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "operationIds": { "alias": "operationIds"; "required": false; "isSignal": true; }; "uniqueOperationIds": { "alias": "uniqueOperationIds"; "required": false; "isSignal": true; }; "appInstanceId": { "alias": "appInstanceId"; "required": false; "isSignal": true; }; "searchDelimiter": { "alias": "searchDelimiter"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof NoopTreeSelectDirective; inputs: {}; outputs: {}; }]>;
42
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<LuCoreSelectDepartmentsDirective<any>, "lu-simple-select[departments],lu-multi-select[departments]", ["luDepartments"], { "url": { "alias": "url"; "required": false; "isSignal": true; }; "countUrl": { "alias": "countUrl"; "required": false; "isSignal": true; }; "filters": { "alias": "filters"; "required": false; "isSignal": true; }; "operationIds": { "alias": "operationIds"; "required": false; "isSignal": true; }; "uniqueOperationIds": { "alias": "uniqueOperationIds"; "required": false; "isSignal": true; }; "appInstanceId": { "alias": "appInstanceId"; "required": false; "isSignal": true; }; "searchDelimiter": { "alias": "searchDelimiter"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof NoopTreeSelectDirective; inputs: {}; outputs: {}; }]>;
42
43
  }
43
44
 
44
45
  interface LuCoreSelectLegalUnit extends ILuApiItem {
@@ -6,7 +6,7 @@ declare class FormHeaderComponent {
6
6
  */
7
7
  readonly headingLevel: i0.InputSignal<1 | 2 | 3 | 4 | 5 | 6>;
8
8
  static ɵfac: i0.ɵɵFactoryDeclaration<FormHeaderComponent, never>;
9
- static ɵcmp: i0.ɵɵComponentDeclaration<FormHeaderComponent, "lu-form-header]", never, { "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
9
+ static ɵcmp: i0.ɵɵComponentDeclaration<FormHeaderComponent, "lu-form-header", never, { "headingLevel": { "alias": "headingLevel"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
10
10
  }
11
11
 
12
12
  /**
@@ -8,7 +8,7 @@ declare class SoftwareIconComponent {
8
8
  readonly domain = "https://cdn.lucca.fr";
9
9
  readonly path = "/transverse/prisme/visuals/software-icon/";
10
10
  readonly extension = ".svg";
11
- readonly icon: _angular_core.InputSignal<"absences" | "timesheet" | "office" | "projects" | "shifts" | "performance" | "engagement" | "training" | "recruitment" | "mood" | "analytics" | "employee-administration" | "shared-documents" | "faces" | "business-expenses" | "invoices" | "payment-methods" | "accounting-assistant" | "certified-einvoicing-platform" | "compensation" | "payslip" | "benefits" | "payroll-assistant" | "cloud-control" | "ask-lucca" | "calendar" | "administration" | "client-center" | "sandbox" | "store" | "lucca">;
11
+ readonly icon: _angular_core.InputSignal<"absences" | "timesheet" | "office" | "projects" | "shifts" | "performance" | "engagement" | "training" | "recruitment" | "mood" | "analytics" | "employee-administration" | "shared-documents" | "faces" | "business-expenses" | "invoices" | "payment-methods" | "accounting-assistant" | "certified-einvoicing-platform" | "compensation" | "payslip" | "benefits" | "payroll-assistant" | "cloud-control" | "ask-lucca" | "ask-salesforce" | "calendar" | "administration" | "client-center" | "sandbox" | "store" | "lucca">;
12
12
  readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
13
13
  readonly withTooltip: _angular_core.InputSignalWithTransform<boolean, unknown>;
14
14
  readonly iconAlt: _angular_core.InputSignal<string>;
@@ -23,7 +23,7 @@ declare class SoftwareIconComponent {
23
23
  */
24
24
  declare const SOFTWARE_ICON_SIZE: readonly ["XXS", "XS", "S", "L"];
25
25
  type SoftwareIconSize = (typeof SOFTWARE_ICON_SIZE)[number];
26
- declare const SOFTWARE_ICON: readonly ["absences", "timesheet", "office", "projects", "shifts", "performance", "engagement", "training", "recruitment", "mood", "analytics", "employee-administration", "shared-documents", "faces", "business-expenses", "invoices", "payment-methods", "accounting-assistant", "certified-einvoicing-platform", "compensation", "payslip", "benefits", "payroll-assistant", "cloud-control", "ask-lucca", "calendar", "administration", "client-center", "sandbox", "store", "lucca"];
26
+ declare const SOFTWARE_ICON: readonly ["absences", "timesheet", "office", "projects", "shifts", "performance", "engagement", "training", "recruitment", "mood", "analytics", "employee-administration", "shared-documents", "faces", "business-expenses", "invoices", "payment-methods", "accounting-assistant", "certified-einvoicing-platform", "compensation", "payslip", "benefits", "payroll-assistant", "cloud-control", "ask-lucca", "ask-salesforce", "calendar", "administration", "client-center", "sandbox", "store", "lucca"];
27
27
  type SoftwareIcon = (typeof SOFTWARE_ICON)[number];
28
28
 
29
29
  export { LU_SOFTWARE_ICON_WRAPPER, SOFTWARE_ICON, SOFTWARE_ICON_SIZE, SoftwareIconComponent };
@@ -169,6 +169,7 @@ declare class TimePickerComponent extends BasePickerComponent {
169
169
  protected readonly hoursDisplay: _angular_core.Signal<number | "––">;
170
170
  protected readonly minutesDisplay: _angular_core.Signal<number | "––">;
171
171
  protected readonly hours: _angular_core.Signal<number>;
172
+ protected readonly hoursInputValue: _angular_core.Signal<number | "––">;
172
173
  protected readonly minutes: _angular_core.Signal<number>;
173
174
  protected readonly pickerClasses: _angular_core.Signal<{
174
175
  [x: string]: boolean;