From 0ad5377535e7c19941da301e8a2ee7298ab70f91 Mon Sep 17 00:00:00 2001 From: Quentin Le Caignec <12102823+QuentinLeCaignec@users.noreply.github.com> Date: Wed, 29 Nov 2023 12:40:10 +0100 Subject: [PATCH 1/6] Fix/table grid view actions (#74) * refactor(redmine 1246968): simplify `ThumbnailGrid` actions and `TableGridView` actions refactor: moved typeGuard helper, added typeGuard for interface, added tests --- .changeset/wet-walls-promise.md | 8 + package-lock.json | 10 +- .../src/helpers/index.ts | 1 + .../src/helpers/typeGuard.test.ts | 55 ++++++ .../src/helpers/typeGuard.ts | 16 ++ .../src/types/actions.ts | 2 +- .../TableGridView/TableGridView.mock.tsx | 168 ++++++++++++++---- .../TableGridView/TableGridView.tsx | 67 ++++--- .../__snapshots__/TableGridView.test.tsx.snap | 22 +-- .../react-front-kit-table/src/types/table.ts | 6 +- .../Components/Thumbnail/Thumbnail.mock.tsx | 2 +- .../Thumbnail/Thumbnail.stories.tsx | 1 + .../src/Components/Thumbnail/Thumbnail.tsx | 33 +--- .../ThumbnailGrid/ThumbnailGrid.mock.tsx | 57 +++--- .../ThumbnailGrid/ThumbnailGrid.test.tsx | 7 +- .../ThumbnailGrid/ThumbnailGrid.tsx | 26 ++- .../__snapshots__/ThumbnailGrid.test.tsx.snap | 77 ++++++++ packages/react-front-kit/src/helpers/index.ts | 1 - packages/react-front-kit/src/index.tsx | 1 + packages/react-front-kit/src/types/index.ts | 1 + .../react-front-kit/src/types/thumbnail.ts | 14 ++ .../Pages/BrowsingPage/BrowsingPage.mock.tsx | 106 +++++------ .../src/Pages/BrowsingPage/BrowsingPage.tsx | 3 +- 23 files changed, 478 insertions(+), 206 deletions(-) create mode 100644 .changeset/wet-walls-promise.md create mode 100644 packages/react-front-kit-shared/src/helpers/typeGuard.test.ts rename packages/{react-front-kit => react-front-kit-shared}/src/helpers/typeGuard.ts (61%) create mode 100644 packages/react-front-kit/src/types/index.ts create mode 100644 packages/react-front-kit/src/types/thumbnail.ts diff --git a/.changeset/wet-walls-promise.md b/.changeset/wet-walls-promise.md new file mode 100644 index 00000000..2a5a37a4 --- /dev/null +++ b/.changeset/wet-walls-promise.md @@ -0,0 +1,8 @@ +--- +'@smile/react-front-kit-shared': minor +'@smile/react-front-kit-table': minor +'@smile/react-front-kit': minor +'storybook-pages': minor +--- + +Refactored actions in `ThumbnailGrid` and `TableGridView` components, moved `typeGuard` helper to shared package, added `typeGuardInterface` function, added tests diff --git a/package-lock.json b/package-lock.json index 28ff84df..81c9f718 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34179,7 +34179,7 @@ }, "packages/react-front-kit": { "name": "@smile/react-front-kit", - "version": "0.4.0", + "version": "0.5.0", "license": "MIT", "dependencies": { "@mantine/dropzone": "^6.0.21", @@ -34221,7 +34221,7 @@ }, "packages/react-front-kit-dropzone": { "name": "@smile/react-front-kit-dropzone", - "version": "0.4.0", + "version": "0.5.0", "license": "MIT", "dependencies": { "@smile/react-front-kit": "*", @@ -35303,7 +35303,7 @@ }, "packages/react-front-kit-shared": { "name": "@smile/react-front-kit-shared", - "version": "0.4.0", + "version": "0.5.0", "license": "MIT", "devDependencies": { "@babel/preset-env": "^7.22.20", @@ -36379,7 +36379,7 @@ }, "packages/react-front-kit-table": { "name": "@smile/react-front-kit-table", - "version": "0.4.0", + "version": "0.5.0", "license": "MIT", "dependencies": { "@smile/react-front-kit": "*", @@ -38505,7 +38505,7 @@ } }, "packages/storybook-pages": { - "version": "0.0.0", + "version": "0.1.0", "license": "MIT", "dependencies": { "@smile/react-front-kit": "*", diff --git a/packages/react-front-kit-shared/src/helpers/index.ts b/packages/react-front-kit-shared/src/helpers/index.ts index 521caef8..a7f9b21d 100644 --- a/packages/react-front-kit-shared/src/helpers/index.ts +++ b/packages/react-front-kit-shared/src/helpers/index.ts @@ -1 +1,2 @@ export * from './utilities'; +export * from './typeGuard'; diff --git a/packages/react-front-kit-shared/src/helpers/typeGuard.test.ts b/packages/react-front-kit-shared/src/helpers/typeGuard.test.ts new file mode 100644 index 00000000..04a431a4 --- /dev/null +++ b/packages/react-front-kit-shared/src/helpers/typeGuard.test.ts @@ -0,0 +1,55 @@ +import { typeGuard, typeGuardInterface } from './typeGuard'; + +interface ITest { + id: number; +} + +describe('typeGuard', () => { + describe('typeGuard', () => { + it('should test if value is correct Primitive or Constructor', () => { + // primitives + expect(typeGuard('string', 'number')).toEqual(false); + expect(typeGuard('string', 'boolean')).toEqual(false); + expect(typeGuard('string', 'string')).toEqual(true); + expect(typeGuard(42, 'number')).toEqual(true); + expect(typeGuard(42, 'boolean')).toEqual(false); + expect(typeGuard(42, 'number')).toEqual(true); + expect(typeGuard(true, 'number')).toEqual(false); + expect(typeGuard(true, 'string')).toEqual(false); + expect(typeGuard(true, 'boolean')).toEqual(true); + expect(typeGuard(false, 'number')).toEqual(false); + expect(typeGuard(false, 'string')).toEqual(false); + expect(typeGuard(false, 'boolean')).toEqual(true); + expect(typeGuard(null, 'number')).toEqual(false); + expect(typeGuard(null, 'string')).toEqual(false); + expect(typeGuard(null, 'boolean')).toEqual(false); + expect(typeGuard(undefined, 'number')).toEqual(false); + expect(typeGuard(undefined, 'string')).toEqual(false); + expect(typeGuard(undefined, 'boolean')).toEqual(false); + // constructor + expect(typeGuard(new Date(), 'number')).toEqual(false); + expect(typeGuard(new Date(), 'boolean')).toEqual(false); + expect(typeGuard(new Date(), 'string')).toEqual(false); + expect(typeGuard('string', Date)).toEqual(false); + expect(typeGuard(42, Date)).toEqual(false); + expect(typeGuard(true, Date)).toEqual(false); + expect(typeGuard(false, Date)).toEqual(false); + expect(typeGuard(null, Date)).toEqual(false); + expect(typeGuard(undefined, Date)).toEqual(false); + expect(typeGuard(new Date(), Date)).toEqual(true); + }); + }); + describe('typeGuardInterface', () => { + it('should test if value is validated as given interface', () => { + expect(typeGuardInterface({}, 'id')).toEqual(false); + expect(typeGuardInterface({ id: 1 }, 'label')).toEqual(false); + expect(typeGuardInterface({ id: 1 }, 'id')).toEqual(true); + expect(typeGuardInterface({ id: 1 }, 'id', 'string')).toEqual( + false, + ); + expect(typeGuardInterface({ id: 1 }, 'id', 'number')).toEqual( + true, + ); + }); + }); +}); diff --git a/packages/react-front-kit/src/helpers/typeGuard.ts b/packages/react-front-kit-shared/src/helpers/typeGuard.ts similarity index 61% rename from packages/react-front-kit/src/helpers/typeGuard.ts rename to packages/react-front-kit-shared/src/helpers/typeGuard.ts index 5a6053ad..00b782fe 100644 --- a/packages/react-front-kit/src/helpers/typeGuard.ts +++ b/packages/react-front-kit-shared/src/helpers/typeGuard.ts @@ -16,6 +16,7 @@ export type IGuardedType = T extends new ( ? ITypeMap[T] : never; +/* Check if value is primitive or class constructor */ export function typeGuard( o: unknown, className: T, @@ -26,3 +27,18 @@ export function typeGuard( } return o instanceof localPrimitiveOrConstructor; } + +/* eslint-disable @typescript-eslint/no-explicit-any */ +export type ITypeGenericInterface = Record; + +/* Validate interface typing of given object by verifying if key exist */ +export function typeGuardInterface( + object: ITypeGenericInterface, + uniqueKey: number | string, + keyType?: unknown, +): object is Type { + return ( + uniqueKey in object && + (keyType ? typeof object[uniqueKey] === keyType : true) + ); +} diff --git a/packages/react-front-kit-shared/src/types/actions.ts b/packages/react-front-kit-shared/src/types/actions.ts index 3fc7c44b..964c96af 100644 --- a/packages/react-front-kit-shared/src/types/actions.ts +++ b/packages/react-front-kit-shared/src/types/actions.ts @@ -30,7 +30,7 @@ export interface IAction { isItemAction?: boolean; isMassAction?: boolean; label: string | ((item: Item) => string); - onAction?: (item: Item) => void; + onAction?: (item: Item | Item[]) => void; } export interface IConfirmAction extends IAction { diff --git a/packages/react-front-kit-table/src/Components/TableGridView/TableGridView.mock.tsx b/packages/react-front-kit-table/src/Components/TableGridView/TableGridView.mock.tsx index db0de669..7744c054 100644 --- a/packages/react-front-kit-table/src/Components/TableGridView/TableGridView.mock.tsx +++ b/packages/react-front-kit-table/src/Components/TableGridView/TableGridView.mock.tsx @@ -1,51 +1,153 @@ -import type { ITableGridViewProps } from './TableGridView'; -import type { HandlerFunction } from '@storybook/addon-actions'; +import type { + ITableGridAction, + ITableGridViewGridProps, + ITableGridViewProps, +} from './TableGridView'; -import { Trash } from '@phosphor-icons/react'; -import { FolderMove } from '@smile/react-front-kit'; -import { thumbnailActionsMock } from '@smile/react-front-kit/mock'; +import { + DownloadSimple, + Eye, + PencilSimple, + ShareNetwork, + Star, + Trash, +} from '@phosphor-icons/react'; +import { FolderMove } from '@smile/react-front-kit-shared'; import { action } from '@storybook/addon-actions'; import { tableMock } from '../Table/Table.mock'; -const gridProps = { +const { actions, data, ...tableProps } = tableMock; +const gridProps: ITableGridViewGridProps = { cols: 5, - gridActions: [ - { - icon: , - id: 'move', - label: 'Move in tree', - onAction: action('Move selected in tree'), - }, - { - color: 'red', - confirmModalProps: { - cancelLabel: 'Abort', - children:

Are you sure ?

, - confirmColor: 'red', - confirmLabel: 'Remove', - title: 'remove x files ?', - }, - confirmation: true, - icon: , - id: 'delete', - label: 'Delete', - onAction: action('Delete selected'), - }, - ], idFieldName: 'id', labelFieldName: 'title', - onThumbnailClick: (): HandlerFunction => action('Thumbnail clicked'), spacing: 25, - thumbnailActions: thumbnailActionsMock, verticalSpacing: 25, }; -const { data, ...tableProps } = tableMock; +export interface IExampleDataType extends Record { + creator: string; + date: string; + format: string; + id: number | string; + title: string; +} + +export const actionsMock: ITableGridAction[] = [ + { + icon: , + id: 'move', + isMassAction: true, + label: 'Move in tree', + onAction: action('Move in tree'), + }, + { + icon: , + id: 'open', + label: 'Open document', + onAction: action('Open document'), + }, + { + icon: , + id: 'edit', + label: 'Edit document', + onAction: action('Edit document'), + }, + { + icon: , + id: 'favorite', + label: 'Add to favorites', + onAction: action('Add to favorites'), + }, + { + confirmation: true, + icon: , + id: 'share', + label: 'Share', + onAction: action('Share'), + }, + { + icon: , + id: 'download', + label: 'Download', + onAction: action('Download'), + }, + { + color: 'red', + confirmModalProps: { + children: 'Are you sure you want to delete ?', + confirmColor: 'red', + confirmLabel: 'Delete', + onCancel: action('Delete:Cancel'), + onConfirm: action('Delete:Confirm'), + title: 'Delete ?', + }, + confirmation: true, + icon: , + id: 'delete', + isMassAction: true, + label: 'Delete', + onAction: action('Delete'), + }, +]; + +export const dataMock: IExampleDataType[] = [ + { + creator: 'Quentin Le Caignec', + date: '16/05/2022', + format: 'SVG', + id: 1, + title: 'Doc test 1', + }, + { + creator: 'Quentin Le Caignec', + date: '17/05/2022', + format: 'PDF', + id: 2, + title: 'Doc test 2', + }, + { + creator: 'Quentin Le Caignec', + date: '18/05/2022', + format: 'ODT', + id: 3, + title: 'Doc test 3', + }, + { + creator: 'Quentin Le Caignec', + date: '19/05/2022', + format: 'DOC', + id: 4, + title: 'Doc test 4', + }, + { + creator: 'Quentin Le Caignec', + date: '20/05/2022', + format: 'JPG', + id: 5, + title: 'Doc test 5', + }, + { + creator: 'Quentin Le Caignec', + date: '21/05/2022', + format: 'PNG', + id: 6, + title: 'Doc test 6', + }, + { + creator: 'Quentin Le Caignec', + date: '22/05/2022', + format: 'PDF', + id: 7, + title: 'Doc test 7', + }, +]; export const tableGridViewProps: ITableGridViewProps> = { - data, + actions: actionsMock, + data: dataMock, gridProps, tableProps, }; diff --git a/packages/react-front-kit-table/src/Components/TableGridView/TableGridView.tsx b/packages/react-front-kit-table/src/Components/TableGridView/TableGridView.tsx index 51dc6c1a..d59697c7 100644 --- a/packages/react-front-kit-table/src/Components/TableGridView/TableGridView.tsx +++ b/packages/react-front-kit-table/src/Components/TableGridView/TableGridView.tsx @@ -1,21 +1,21 @@ +import type { ITableData } from '../../types'; import type { ITableProps } from '../Table/Table'; +import type { Record } from '@phosphor-icons/react'; import type { + IAction, IDataView, ISwitchableViewProps, IThumbnail, + IThumbnailData, IThumbnailGridProps, } from '@smile/react-front-kit'; import type { MRT_RowSelectionState } from 'mantine-react-table'; -import type { ReactElement } from 'react'; +import type { ReactElement, SetStateAction } from 'react'; import { createStyles } from '@mantine/styles'; import { ListBullets, SquaresFour } from '@phosphor-icons/react'; -import { - SwitchableView, - ThumbnailGrid, - isNotNullNorEmpty, - typeGuard, -} from '@smile/react-front-kit'; +import { SwitchableView, ThumbnailGrid } from '@smile/react-front-kit'; +import { isNotNullNorEmpty, typeGuard } from '@smile/react-front-kit-shared'; import { useState } from 'react'; import { Table } from '../Table/Table'; @@ -27,26 +27,38 @@ const useStyles = createStyles(() => ({ }, })); +export type ITableGridAction> = IAction< + ITableData | IThumbnailData +>; + export interface ITableGridViewGridProps - extends Omit { + extends Omit< + IThumbnailGridProps, + 'actions' | 'onThumbnailClick' | 'thumbnails' + > { iconTypeFieldName?: string; idFieldName: string; imageFieldName?: string; labelFieldName: string; } +export type ITableGridViewTableProps> = + Omit, 'actions' | 'data'>; + export interface ITableGridViewProps> extends Omit { + actions?: ITableGridAction[]; data: Data[]; defaultView?: 'grid' | 'table'; gridProps: ITableGridViewGridProps; - tableProps: Omit, 'data'>; + tableProps: ITableGridViewTableProps; } export function TableGridView>( props: ITableGridViewProps, ): ReactElement { const { + actions = [], data, defaultView = 'table', gridProps, @@ -64,19 +76,8 @@ export function TableGridView>( const selectedIndexes = Object.entries(rowSelection).map((entry) => entry[1] ? entry[0] : null, ); - const { classes } = useStyles(); - const extendedTableProps: ITableProps = { - data, - enableBottomToolbar: false, - enableRowSelection: true, - mantinePaperProps: { - className: classes.tablePaper, - }, - onRowSelectionChange: setRowSelection, - state: { rowSelection }, - ...tableProps, - }; + const { classes } = useStyles(); const thumbnails: IThumbnail[] = data .map((item, index) => { @@ -110,21 +111,43 @@ export function TableGridView>( }) .filter(isNotNullNorEmpty); + function handleTableSelect(row: SetStateAction): void { + setRowSelection(row); + } + function handleThumbnailSelect(index: number): void { const newRowSelection = { ...rowSelection }; newRowSelection[index] = !newRowSelection[index]; setRowSelection(newRowSelection); } + const extendedTableProps: ITableProps = { + data, + enableBottomToolbar: false, + enableRowSelection: true, + mantinePaperProps: { + className: classes.tablePaper, + }, + onRowSelectionChange: handleTableSelect, + state: { rowSelection }, + ...tableProps, + }; + const views: IDataView[] = [ { - dataView: , + dataView: ( +
>[]} + {...extendedTableProps} + /> + ), label: , value: 'table', }, { dataView: ( []} thumbnails={thumbnails} {...otherGridProps} onThumbnailClick={(_, i) => handleThumbnailSelect(i)} diff --git a/packages/react-front-kit-table/src/Components/TableGridView/__snapshots__/TableGridView.test.tsx.snap b/packages/react-front-kit-table/src/Components/TableGridView/__snapshots__/TableGridView.test.tsx.snap index 03f24fde..88afb870 100644 --- a/packages/react-front-kit-table/src/Components/TableGridView/__snapshots__/TableGridView.test.tsx.snap +++ b/packages/react-front-kit-table/src/Components/TableGridView/__snapshots__/TableGridView.test.tsx.snap @@ -916,7 +916,7 @@ exports[`TableGridView matches snapshot 1`] = `
- Valentin Perello + Quentin Le Caignec - Valentin Perello + Quentin Le Caignec - PDF + ODT - Valentin Perello + Quentin Le Caignec - PDF + DOC - Valentin Perello + Quentin Le Caignec - PDF + JPG - Valentin Perello + Quentin Le Caignec - PDF + PNG - Valentin Perello + Quentin Le Caignec - Valentin Perello + Quentin Le Caignec > = + | MRT_Row + | MRT_Row[]; + export type ITableAction> = IAction< - MRT_Row | MRT_Row[] + ITableData >; export type ITableConfirmAction> = diff --git a/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.mock.tsx b/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.mock.tsx index e237c9b0..c79413c3 100644 --- a/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.mock.tsx +++ b/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.mock.tsx @@ -1,4 +1,4 @@ -import type { IThumbnailAction } from './Thumbnail'; +import type { IThumbnailAction } from '../../types'; import { DownloadSimple, diff --git a/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.stories.tsx b/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.stories.tsx index c9d96edd..2a5b1565 100644 --- a/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.stories.tsx +++ b/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.stories.tsx @@ -18,6 +18,7 @@ export const Thumbnail: IStory = { iconType: 'PDF', id: '1', label: 'Debit_Suivi_PREV', + onActionOverride: undefined, selected: false, }, }; diff --git a/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.tsx b/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.tsx index fe0895c9..c67847f0 100644 --- a/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.tsx +++ b/packages/react-front-kit/src/Components/Thumbnail/Thumbnail.tsx @@ -1,9 +1,7 @@ 'use client'; -import type { - IAction, - IActionConfirmModalProps, -} from '@smile/react-front-kit-shared'; +import type { IThumbnail, IThumbnailAction } from '../../types'; +import type { IActionConfirmModalProps } from '@smile/react-front-kit-shared'; import type { ReactElement } from 'react'; import { @@ -24,23 +22,11 @@ import { ConfirmModal } from '../ConfirmModal/ConfirmModal'; import { useStyles } from './Thumbnail.style'; -export interface IThumbnail extends Record { - iconType?: string; - id: number | string; - image?: string; - label?: string; - onClick?: () => void; - selected?: boolean; -} - -export type IThumbnailAction = IAction; - export interface IThumbnailProps extends IThumbnail { actions?: IThumbnailAction[]; } export function Thumbnail(props: IThumbnailProps): ReactElement { - const { classes } = useStyles(); const theme = useMantineTheme(); const { actions = [], @@ -50,10 +36,11 @@ export function Thumbnail(props: IThumbnailProps): ReactElement { onClick, selected = false, } = props; - const [confirmAction, setConfirmAction] = useState | null>(null); + const { classes } = useStyles(); + function clearConfirmAction(): void { setConfirmAction(null); } @@ -87,8 +74,8 @@ export function Thumbnail(props: IThumbnailProps): ReactElement { clearConfirmAction(); } - function handleModalButton(onAction?: (item: IThumbnail) => void): void { - onAction && onAction(props); + function handleModalButton(onModalAction?: (item: IThumbnail) => void): void { + onModalAction?.(props); handleClose(); } @@ -165,13 +152,9 @@ export function Thumbnail(props: IThumbnailProps): ReactElement { - handleModalButton(confirmAction?.onCancel && confirmAction.onCancel) - } + onCancel={() => handleModalButton(confirmAction?.onCancel)} onClose={handleClose} - onConfirm={() => - handleModalButton(confirmAction?.onConfirm && confirmAction.onConfirm) - } + onConfirm={() => handleModalButton(confirmAction?.onConfirm)} opened={Boolean(confirmAction)} > {confirmAction?.children} diff --git a/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.mock.tsx b/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.mock.tsx index 1126b45a..d02499dd 100644 --- a/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.mock.tsx +++ b/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.mock.tsx @@ -1,4 +1,4 @@ -import type { IThumbnail } from '../Thumbnail/Thumbnail'; +import type { IThumbnail, IThumbnailAction } from '../../types'; import type { HandlerFunction } from '@storybook/addon-actions'; import { Trash } from '@phosphor-icons/react'; @@ -7,8 +7,36 @@ import { action } from '@storybook/addon-actions'; import { thumbnailActionsMock } from '../Thumbnail/Thumbnail.mock'; +export const thumbnailGridActionsMock: IThumbnailAction[] = [ + { + icon: , + id: 'move', + isItemAction: false, + isMassAction: true, + label: 'Move in tree', + onAction: action('Move selected in tree'), + }, + { + color: 'red', + confirmModalProps: { + cancelLabel: 'Abort', + children:

Are you sure ?

, + confirmColor: 'red', + confirmLabel: 'Remove', + title: 'remove x files ?', + }, + confirmation: true, + icon: , + id: 'delete', + isItemAction: false, + isMassAction: true, + label: 'Delete', + onAction: action('Delete selected'), + }, + ...thumbnailActionsMock, +]; + export const baseThumbnailMock: Omit = { - actions: thumbnailActionsMock, iconType: 'PDF', }; @@ -32,30 +60,9 @@ export const thumbnails: IThumbnail[] = [ ]; export const thumbnailGridMock = { + actions: thumbnailGridActionsMock, cols: 5, - gridActions: [ - { - icon: , - id: 'move', - label: 'Move in tree', - onAction: action('Move selected in tree'), - }, - { - color: 'red', - confirmModalProps: { - cancelLabel: 'Abort', - children:

Are you sure ?

, - confirmColor: 'red', - confirmLabel: 'Remove', - title: 'remove x files ?', - }, - confirmation: true, - icon: , - id: 'delete', - label: 'Delete', - onAction: action('Delete selected'), - }, - ], + onActionOverride: undefined, onThumbnailClick: (): HandlerFunction => action('Thumbnail clicked'), spacing: 25, thumbnails, diff --git a/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.test.tsx b/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.test.tsx index 561123d5..56f5f54c 100644 --- a/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.test.tsx +++ b/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.test.tsx @@ -1,7 +1,7 @@ import { renderWithProviders } from '@smile/react-front-kit-shared/test-utils'; import { ThumbnailGrid } from './ThumbnailGrid'; -import { thumbnails } from './ThumbnailGrid.mock'; +import { thumbnailGridActionsMock, thumbnails } from './ThumbnailGrid.mock'; describe('ThumbnailGrid', () => { beforeEach(() => { @@ -10,7 +10,10 @@ describe('ThumbnailGrid', () => { }); it('matches snapshot', () => { const { container } = renderWithProviders( - , + , ); expect(container).toMatchSnapshot(); }); diff --git a/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.tsx b/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.tsx index 455115a7..5999dea8 100644 --- a/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.tsx +++ b/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.tsx @@ -1,11 +1,8 @@ 'use client'; -import type { IThumbnail, IThumbnailAction } from '../Thumbnail/Thumbnail'; +import type { IThumbnail, IThumbnailAction } from '../../types'; import type { SimpleGridProps } from '@mantine/core'; -import type { - IAction, - IActionConfirmModalProps, -} from '@smile/react-front-kit-shared'; +import type { IActionConfirmModalProps } from '@smile/react-front-kit-shared'; import type { ReactElement } from 'react'; import { Button, Group, SimpleGrid } from '@mantine/core'; @@ -36,24 +33,21 @@ function defaultSelectedElementsText(n: number): string { return `${n} selected file${n > 1 ? 's' : ''}`; } -type IGridAction = IAction; type IGridActionConfirmModalProps = IActionConfirmModalProps; export interface IThumbnailGridProps extends SimpleGridProps { - gridActions?: IGridAction[]; + actions?: IThumbnailAction[]; onThumbnailClick?: (item: IThumbnail, index: number) => void; selectedElementsText?: (numberOfSelectedElements: number) => string; - thumbnailActions?: IThumbnailAction[]; thumbnails: IThumbnail[]; } /** Additional props will be forwarded to the [Mantine SimpleGrid component](https://mantine.dev/core/simple-grid) */ export function ThumbnailGrid(props: IThumbnailGridProps): ReactElement { const { - gridActions = [], + actions = [], onThumbnailClick, selectedElementsText = defaultSelectedElementsText, - thumbnailActions, thumbnails, ...simpleGridProps } = props; @@ -62,6 +56,8 @@ export function ThumbnailGrid(props: IThumbnailGridProps): ReactElement { const numberOfSelectedElements = selectedElements.length; const [confirmAction, setConfirmAction] = useState(null); + const massActions = actions.filter(({ isMassAction }) => isMassAction); + const itemActions = actions.filter(({ isItemAction = true }) => isItemAction); const { classes } = useStyles(); @@ -69,7 +65,7 @@ export function ThumbnailGrid(props: IThumbnailGridProps): ReactElement { onThumbnailClick?.(thumbnails[index], index); } - function setModal(action: IGridAction): void { + function setModal(action: IThumbnailAction): void { setConfirmAction({ cancelColor: action.confirmModalProps?.cancelColor, cancelLabel: action.confirmModalProps?.cancelLabel, @@ -81,7 +77,7 @@ export function ThumbnailGrid(props: IThumbnailGridProps): ReactElement { }); } - function handleGridAction(action: IGridAction): void { + function handleGridAction(action: IThumbnailAction): void { if (action.confirmation) { setModal(action); } else { @@ -108,9 +104,9 @@ export function ThumbnailGrid(props: IThumbnailGridProps): ReactElement { {numberOfSelectedElements > 0 && (
{selectedElementsText(numberOfSelectedElements)} - {gridActions.length > 0 && ( + {massActions.length > 0 && ( - {gridActions.map((action) => ( + {massActions.map((action) => ( + +
{ + iconType?: string; + id: number | string; + image?: string; + label?: string; + onClick?: () => void; + selected?: boolean; +} + +export type IThumbnailData = IThumbnail | IThumbnail[]; + +export type IThumbnailAction = IAction; diff --git a/packages/storybook-pages/src/Pages/BrowsingPage/BrowsingPage.mock.tsx b/packages/storybook-pages/src/Pages/BrowsingPage/BrowsingPage.mock.tsx index 23344769..eb89b845 100644 --- a/packages/storybook-pages/src/Pages/BrowsingPage/BrowsingPage.mock.tsx +++ b/packages/storybook-pages/src/Pages/BrowsingPage/BrowsingPage.mock.tsx @@ -1,7 +1,8 @@ import type { ITableGridViewGridProps, - ITableProps, + ITableGridViewTableProps, } from '@smile/react-front-kit-table'; +import type { IExampleDataType } from '@smile/react-front-kit-table/mock'; import { DownloadSimple, @@ -12,15 +13,47 @@ import { Trash, } from '@phosphor-icons/react'; import { FolderMove } from '@smile/react-front-kit'; -import { thumbnailActionsMock } from '@smile/react-front-kit/mock'; -interface IExampleDataType extends Record { - creator: string; - date: string; - format: string; - id: number | string; - title: string; -} +export const actions = [ + { + icon: , + id: 'move', + isMassAction: true, + label: "Déplacer dans l'arborescence", + }, + { + icon: , + id: 'open', + label: 'Ouvrir', + }, + { + icon: , + id: 'edit', + label: 'Modifier', + }, + { + icon: , + id: 'favorite', + label: 'Ajouter aux favoris', + }, + { + confirmation: true, + icon: , + id: 'share', + label: 'Partager', + }, + { + icon: , + id: 'download', + label: 'Télécharger', + }, + { + icon: , + id: 'delete', + isMassAction: true, + label: 'Supprimer', + }, +]; export const data: IExampleDataType[] = [ { @@ -74,47 +107,7 @@ export const data: IExampleDataType[] = [ }, ]; -export const tableProps: Omit, 'data'> = { - actions: [ - { - icon: , - id: 'move', - isMassAction: true, - label: "Déplacer dans l'arborescence", - }, - { - icon: , - id: 'open', - label: 'Ouvrir', - }, - { - icon: , - id: 'edit', - label: 'Modifier', - }, - { - icon: , - id: 'favorite', - label: 'Ajouter aux favoris', - }, - { - confirmation: true, - icon: , - id: 'share', - label: 'Partager', - }, - { - icon: , - id: 'download', - label: 'Télécharger', - }, - { - icon: , - id: 'delete', - isMassAction: true, - label: 'Supprimer', - }, - ], +export const tableProps: ITableGridViewTableProps = { columns: [ { accessorKey: 'format', @@ -162,23 +155,10 @@ export const tableProps: Omit, 'data'> = { export const gridProps: ITableGridViewGridProps = { cols: 5, - gridActions: [ - { - icon: , - id: 'move', - label: "Déplacer dans l'arborescence", - }, - { - icon: , - id: 'delete', - label: 'Supprimer', - }, - ], iconTypeFieldName: 'format', idFieldName: 'id', labelFieldName: 'title', selectedElementsText: (n) => `${n} fichier(s) sélectionnés`, spacing: 25, - thumbnailActions: thumbnailActionsMock, verticalSpacing: 25, }; diff --git a/packages/storybook-pages/src/Pages/BrowsingPage/BrowsingPage.tsx b/packages/storybook-pages/src/Pages/BrowsingPage/BrowsingPage.tsx index c860f4b7..b6d841e1 100644 --- a/packages/storybook-pages/src/Pages/BrowsingPage/BrowsingPage.tsx +++ b/packages/storybook-pages/src/Pages/BrowsingPage/BrowsingPage.tsx @@ -27,7 +27,7 @@ import { useState } from 'react'; import { headerContent, headerLeft, headerRight } from '../pages.mock'; -import { data, gridProps, tableProps } from './BrowsingPage.mock'; +import { actions, data, gridProps, tableProps } from './BrowsingPage.mock'; /** * Primary UI component for user interaction @@ -135,6 +135,7 @@ export function BrowsingPage(): ReactElement { Date: Wed, 29 Nov 2023 14:30:52 +0100 Subject: [PATCH 2/6] chore: update changeset configuration and ci config (#75) --- .changeset/config.json | 2 +- .github/workflows/deploy.yml | 4 +- .github/workflows/test-deploy.yml | 44 + package-lock.json | 3092 +---------------- .../react-front-kit-dropzone/package.json | 4 +- packages/react-front-kit-table/package.json | 4 +- packages/react-front-kit/package.json | 5 +- 7 files changed, 222 insertions(+), 2933 deletions(-) create mode 100644 .github/workflows/test-deploy.yml diff --git a/.changeset/config.json b/.changeset/config.json index 11f3a1ce..31d36541 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,7 +7,7 @@ } ], "commit": false, - "fixed": [["@smile/react-front-kit*"]], + "fixed": [["@smile/react-front-kit*", "storybook-pages"]], "access": "public", "baseBranch": "main", "updateInternalDependencies": "patch", diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index d1d02f0f..e1649fbf 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -4,8 +4,8 @@ name: Deploy storybook to Pages on: # Runs on pushes targeting the default branch push: - branches: ['main'] - + branches: + - 'main' # Allows you to run this workflow manually from the Actions tab workflow_dispatch: diff --git a/.github/workflows/test-deploy.yml b/.github/workflows/test-deploy.yml new file mode 100644 index 00000000..54a5f0bb --- /dev/null +++ b/.github/workflows/test-deploy.yml @@ -0,0 +1,44 @@ +# Simple workflow for building static storybook +name: Build storybook + +on: + # Runs on pull_request targeting the main branch + pull_request: + branches: + - 'main' + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Detect package manager + id: detect-package-manager + run: | + if [ -f "${{ github.workspace }}/yarn.lock" ]; then + echo "manager=yarn" >> $GITHUB_OUTPUT + echo "command=install" >> $GITHUB_OUTPUT + echo "runner=yarn" >> $GITHUB_OUTPUT + exit 0 + elif [ -f "${{ github.workspace }}/package.json" ]; then + echo "manager=npm" >> $GITHUB_OUTPUT + echo "command=ci" >> $GITHUB_OUTPUT + echo "runner=npx --no-install" >> $GITHUB_OUTPUT + exit 0 + else + echo "Unable to determine package manager" + exit 1 + fi + - name: Setup Node + uses: actions/setup-node@v3 + with: + node-version: '18' + cache: ${{ steps.detect-package-manager.outputs.manager }} + - name: Install dependencies + run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} + - name: Build storybook + run: ${{ steps.detect-package-manager.outputs.manager }} run build-storybook diff --git a/package-lock.json b/package-lock.json index 81c9f718..252d2bcb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5600,6 +5600,7 @@ "version": "6.0.21", "resolved": "https://registry.npmjs.org/@mantine/dropzone/-/dropzone-6.0.21.tgz", "integrity": "sha512-v63tL4x7R1CvBNnxJVaVPhBVnQcfROQvyOV0xK/v0ZGNAzFxjJoiCRMGdlBjxnEawM0dRhNs/46ItpBgjQIr6g==", + "peer": true, "dependencies": { "@mantine/utils": "6.0.21", "react-dropzone": "14.2.3" @@ -11842,6 +11843,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz", "integrity": "sha512-7prDjvt9HmqiZ0cl5CRjtS84sEyhsHP2coDkaZKRKVfCDo9s7iw7ChVmar78Gu9pC4SoR/28wFu/G5JJhTnqEg==", + "peer": true, "engines": { "node": ">=4" } @@ -17478,6 +17480,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/file-selector/-/file-selector-0.6.0.tgz", "integrity": "sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==", + "peer": true, "dependencies": { "tslib": "^2.4.0" }, @@ -19365,14 +19368,6 @@ "node": ">=8" } }, - "node_modules/install": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", - "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/internal-slot": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", @@ -25839,164 +25834,6 @@ "node": ">=0.10.0" } }, - "node_modules/npm": { - "version": "10.2.4", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.2.4.tgz", - "integrity": "sha512-umEuYneVEYO9KoEEI8n2sSGmNQeqco/3BSeacRlqIkCzw4E7XGtYSWMeJobxzr6hZ2n9cM+u5TsMTcC5bAgoWA==", - "bundleDependencies": [ - "@isaacs/string-locale-compare", - "@npmcli/arborist", - "@npmcli/config", - "@npmcli/fs", - "@npmcli/map-workspaces", - "@npmcli/package-json", - "@npmcli/promise-spawn", - "@npmcli/run-script", - "@sigstore/tuf", - "abbrev", - "archy", - "cacache", - "chalk", - "ci-info", - "cli-columns", - "cli-table3", - "columnify", - "fastest-levenshtein", - "fs-minipass", - "glob", - "graceful-fs", - "hosted-git-info", - "ini", - "init-package-json", - "is-cidr", - "json-parse-even-better-errors", - "libnpmaccess", - "libnpmdiff", - "libnpmexec", - "libnpmfund", - "libnpmhook", - "libnpmorg", - "libnpmpack", - "libnpmpublish", - "libnpmsearch", - "libnpmteam", - "libnpmversion", - "make-fetch-happen", - "minimatch", - "minipass", - "minipass-pipeline", - "ms", - "node-gyp", - "nopt", - "normalize-package-data", - "npm-audit-report", - "npm-install-checks", - "npm-package-arg", - "npm-pick-manifest", - "npm-profile", - "npm-registry-fetch", - "npm-user-validate", - "npmlog", - "p-map", - "pacote", - "parse-conflict-json", - "proc-log", - "qrcode-terminal", - "read", - "semver", - "spdx-expression-parse", - "ssri", - "strip-ansi", - "supports-color", - "tar", - "text-table", - "tiny-relative-date", - "treeverse", - "validate-npm-package-name", - "which", - "write-file-atomic" - ], - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.2.1", - "@npmcli/config": "^8.0.2", - "@npmcli/fs": "^3.1.0", - "@npmcli/map-workspaces": "^3.0.4", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.2", - "@sigstore/tuf": "^2.2.0", - "abbrev": "^2.0.0", - "archy": "~1.0.0", - "cacache": "^18.0.0", - "chalk": "^5.3.0", - "ci-info": "^4.0.0", - "cli-columns": "^4.0.0", - "cli-table3": "^0.6.3", - "columnify": "^1.6.0", - "fastest-levenshtein": "^1.0.16", - "fs-minipass": "^3.0.3", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.1", - "ini": "^4.1.1", - "init-package-json": "^6.0.0", - "is-cidr": "^5.0.3", - "json-parse-even-better-errors": "^3.0.0", - "libnpmaccess": "^8.0.1", - "libnpmdiff": "^6.0.3", - "libnpmexec": "^7.0.4", - "libnpmfund": "^5.0.1", - "libnpmhook": "^10.0.0", - "libnpmorg": "^6.0.1", - "libnpmpack": "^6.0.3", - "libnpmpublish": "^9.0.2", - "libnpmsearch": "^7.0.0", - "libnpmteam": "^6.0.0", - "libnpmversion": "^5.0.1", - "make-fetch-happen": "^13.0.0", - "minimatch": "^9.0.3", - "minipass": "^7.0.4", - "minipass-pipeline": "^1.2.4", - "ms": "^2.1.2", - "node-gyp": "^10.0.1", - "nopt": "^7.2.0", - "normalize-package-data": "^6.0.0", - "npm-audit-report": "^5.0.0", - "npm-install-checks": "^6.3.0", - "npm-package-arg": "^11.0.1", - "npm-pick-manifest": "^9.0.0", - "npm-profile": "^9.0.0", - "npm-registry-fetch": "^16.1.0", - "npm-user-validate": "^2.0.0", - "npmlog": "^7.0.1", - "p-map": "^4.0.0", - "pacote": "^17.0.4", - "parse-conflict-json": "^3.0.1", - "proc-log": "^3.0.0", - "qrcode-terminal": "^0.12.0", - "read": "^2.1.0", - "semver": "^7.5.4", - "spdx-expression-parse": "^3.0.1", - "ssri": "^10.0.5", - "strip-ansi": "^7.1.0", - "supports-color": "^9.4.0", - "tar": "^6.2.0", - "text-table": "~0.2.0", - "tiny-relative-date": "^1.3.0", - "treeverse": "^3.0.0", - "validate-npm-package-name": "^5.0.0", - "which": "^4.0.0", - "write-file-atomic": "^5.0.1" - }, - "bin": { - "npm": "bin/npm-cli.js", - "npx": "bin/npx-cli.js" - }, - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -26008,2809 +25845,222 @@ "node": ">=8" } }, - "node_modules/npm/node_modules/@colors/colors": { - "version": "1.5.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=0.1.90" - } + "node_modules/nwsapi": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", + "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", + "dev": true }, - "node_modules/npm/node_modules/@isaacs/cliui": { - "version": "8.0.2", - "inBundle": true, - "license": "ISC", + "node_modules/nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" }, - "engines": { - "node": ">=12" - } - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "bin": { + "nyc": "bin/nyc.js" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8.9" } }, - "node_modules/npm/node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.2.0", - "inBundle": true, - "license": "ISC", + "node_modules/nyc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.2.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.0", - "@npmcli/installed-package-contents": "^2.0.2", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.0.0", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/query": "^3.0.1", - "@npmcli/run-script": "^7.0.2", - "bin-links": "^4.0.1", - "cacache": "^18.0.0", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.1", - "json-parse-even-better-errors": "^3.0.0", - "json-stringify-nice": "^1.1.4", - "minimatch": "^9.0.0", - "nopt": "^7.0.0", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.1", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "parse-conflict-json": "^3.0.0", - "proc-log": "^3.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^1.0.2", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^10.0.5", - "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" - }, - "bin": { - "arborist": "bin/index.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" + "node_modules/nyc/node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" } }, - "node_modules/npm/node_modules/@npmcli/config": { - "version": "8.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/map-workspaces": "^3.0.2", - "ci-info": "^4.0.0", - "ini": "^4.1.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.5", - "walk-up-path": "^3.0.1" + "node_modules/nyc/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/npm/node_modules/@npmcli/disparity-colors": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", + "node_modules/nyc/node_modules/foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, "dependencies": { - "ansi-styles": "^4.3.0" + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8.0.0" } }, - "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": { - "version": "4.3.0", - "inBundle": true, - "license": "MIT", + "node_modules/nyc/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, "dependencies": { - "color-convert": "^2.0.1" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" }, "engines": { - "node": ">=8" + "node": "*" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/npm/node_modules/@npmcli/fs": { - "version": "3.1.0", - "inBundle": true, - "license": "ISC", + "node_modules/nyc/node_modules/istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, "dependencies": { - "semver": "^7.3.5" + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/npm/node_modules/@npmcli/git": { - "version": "5.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^3.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^4.0.0" + "node_modules/nyc/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "2.0.2", - "inBundle": true, - "license": "ISC", + "node_modules/nyc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "bin": { - "installed-package-contents": "lib/index.js" + "brace-expansion": "^1.1.7" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "*" } }, - "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "3.0.4", - "inBundle": true, - "license": "ISC", + "node_modules/nyc/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" + "p-limit": "^2.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "7.0.0", - "inBundle": true, - "license": "ISC", + "node_modules/nyc/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/nyc/node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/nyc/node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, "dependencies": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^17.0.0", - "semver": "^7.3.5" + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": ">=0.10.0" } }, - "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "5.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^3.0.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "7.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "7.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "read-package-json-fast": "^3.0.0", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "inBundle": true, - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "2.1.0", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.2.1", - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign": { - "version": "2.2.0", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "make-fetch-happen": "^13.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "2.2.0", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.2.1", - "tuf-js": "^2.1.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@tufjs/models": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/abbrev": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/abort-controller": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "event-target-shim": "^5.0.0" - }, - "engines": { - "node": ">=6.5" - } - }, - "node_modules/npm/node_modules/agent-base": { - "version": "7.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/aggregate-error": { - "version": "3.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/npm/node_modules/ansi-styles": { - "version": "6.2.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/aproba": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/archy": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/are-we-there-yet": { - "version": "4.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^4.1.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/base64-js": { - "version": "1.5.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/bin-links": { - "version": "4.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/binary-extensions": { - "version": "2.2.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/npm/node_modules/buffer": { - "version": "6.0.3", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/npm/node_modules/builtins": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "semver": "^7.0.0" - } - }, - "node_modules/npm/node_modules/cacache": { - "version": "18.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/chalk": { - "version": "5.3.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/npm/node_modules/chownr": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/ci-info": { - "version": "4.0.0", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cidr-regex": { - "version": "4.0.3", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "^5.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/clean-stack": { - "version": "2.2.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/cli-columns/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cli-columns/node_modules/strip-ansi": { - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cli-table3": { - "version": "0.6.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - }, - "optionalDependencies": { - "@colors/colors": "1.5.0" - } - }, - "node_modules/npm/node_modules/clone": { - "version": "1.0.4", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/npm/node_modules/cmd-shim": { - "version": "6.0.2", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/color-convert": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/npm/node_modules/color-name": { - "version": "1.1.4", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/color-support": { - "version": "1.1.3", - "inBundle": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/npm/node_modules/columnify": { - "version": "1.6.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/npm/node_modules/columnify/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/columnify/node_modules/strip-ansi": { - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/console-control-strings": { - "version": "1.1.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/cross-spawn": { - "version": "7.0.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/cross-spawn/node_modules/which": { - "version": "2.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/cssesc": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/debug": { - "version": "4.3.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/debug/node_modules/ms": { - "version": "2.1.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/defaults": { - "version": "1.0.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/delegates": { - "version": "1.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/diff": { - "version": "5.1.0", - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/npm/node_modules/eastasianwidth": { - "version": "0.2.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/npm/node_modules/env-paths": { - "version": "2.2.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/err-code": { - "version": "2.0.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/event-target-shim": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/events": { - "version": "3.3.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.1", - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/npm/node_modules/fastest-levenshtein": { - "version": "1.0.16", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/npm/node_modules/foreground-child": { - "version": "3.1.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/fs-minipass": { - "version": "3.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/function-bind": { - "version": "1.1.2", - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/npm/node_modules/gauge": { - "version": "5.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^4.0.1", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/gauge/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/gauge/node_modules/strip-ansi": { - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/glob": { - "version": "10.3.10", - "inBundle": true, - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.5", - "minimatch": "^9.0.1", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", - "path-scurry": "^1.10.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/graceful-fs": { - "version": "4.2.11", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/has-unicode": { - "version": "2.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/hasown": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/npm/node_modules/hosted-git-info": { - "version": "7.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.1.1", - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npm/node_modules/http-proxy-agent": { - "version": "7.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/ieee754": { - "version": "1.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/npm/node_modules/ignore-walk": { - "version": "6.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/npm/node_modules/indent-string": { - "version": "4.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/ini": { - "version": "4.1.1", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/init-package-json": { - "version": "6.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^2.0.0", - "read-package-json": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/ip": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/ip-regex": { - "version": "5.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/is-cidr": { - "version": "5.0.3", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "cidr-regex": "4.0.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/npm/node_modules/is-core-module": { - "version": "2.13.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/is-lambda": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/isexe": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/jackspeak": { - "version": "2.3.6", - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/json-stringify-nice": { - "version": "1.1.4", - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/jsonparse": { - "version": "1.3.1", - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff": { - "version": "6.0.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff-apply": { - "version": "5.5.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/disparity-colors": "^3.0.0", - "@npmcli/installed-package-contents": "^2.0.2", - "binary-extensions": "^2.2.0", - "diff": "^5.1.0", - "minimatch": "^9.0.0", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4", - "tar": "^6.2.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmexec": { - "version": "7.0.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "ci-info": "^4.0.0", - "npm-package-arg": "^11.0.1", - "npmlog": "^7.0.1", - "pacote": "^17.0.4", - "proc-log": "^3.0.0", - "read": "^2.0.0", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "walk-up-path": "^3.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmfund": { - "version": "5.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmhook": { - "version": "10.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmpack": { - "version": "6.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^7.2.1", - "@npmcli/run-script": "^7.0.2", - "npm-package-arg": "^11.0.1", - "pacote": "^17.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.1", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.7", - "sigstore": "^2.1.0", - "ssri": "^10.0.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmsearch": { - "version": "7.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmteam": { - "version": "6.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^16.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/libnpmversion": { - "version": "5.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.3", - "@npmcli/run-script": "^7.0.2", - "json-parse-even-better-errors": "^3.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/lru-cache": { - "version": "10.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/npm/node_modules/make-fetch-happen": { - "version": "13.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/minimatch": { - "version": "9.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/minipass": { - "version": "7.0.4", - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/npm/node_modules/minipass-collect": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-collect/node_modules/minipass": { - "version": "3.3.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-fetch": { - "version": "3.0.4", - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-json-stream": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "jsonparse": "^1.3.1", - "minipass": "^3.0.0" - } - }, - "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": { - "version": "3.3.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-pipeline": { - "version": "1.2.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minizlib": { - "version": "2.1.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/mkdirp": { - "version": "1.0.4", - "inBundle": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/ms": { - "version": "2.1.3", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/mute-stream": { - "version": "1.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/negotiator": { - "version": "0.6.3", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npm/node_modules/node-gyp": { - "version": "10.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^4.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/nopt": { - "version": "7.2.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/normalize-package-data": { - "version": "6.0.0", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^7.0.0", - "is-core-module": "^2.8.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-audit-report": { - "version": "5.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-bundled": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-install-checks": { - "version": "6.3.0", - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^3.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-packlist": { - "version": "8.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "ignore-walk": "^6.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "9.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-profile": { - "version": "9.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "16.1.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-json-stream": "^1.0.1", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npm-user-validate": { - "version": "2.0.0", - "inBundle": true, - "license": "BSD-2-Clause", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/npmlog": { - "version": "7.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^4.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^5.0.0", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/p-map": { - "version": "4.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/pacote": { - "version": "17.0.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^7.0.0", - "cacache": "^18.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^16.0.0", - "proc-log": "^3.0.0", - "promise-retry": "^2.0.1", - "read-package-json": "^7.0.0", - "read-package-json-fast": "^3.0.0", - "sigstore": "^2.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "lib/bin.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/parse-conflict-json": { - "version": "3.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "just-diff": "^6.0.0", - "just-diff-apply": "^5.2.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/path-key": { - "version": "3.1.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/path-scurry": { - "version": "1.10.1", - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "6.0.13", - "inBundle": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/proc-log": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/process": { - "version": "0.11.10", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, - "node_modules/npm/node_modules/promise-all-reject-late": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-call-limit": { - "version": "1.0.2", - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-inflight": { - "version": "1.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/promzard": { - "version": "1.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "^2.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/qrcode-terminal": { - "version": "0.12.0", - "inBundle": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, - "node_modules/npm/node_modules/read": { - "version": "2.1.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "~1.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-cmd-shim": { - "version": "4.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json": { - "version": "7.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "glob": "^10.2.2", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/read-package-json-fast": { - "version": "3.0.2", - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/readable-stream": { - "version": "4.4.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10", - "string_decoder": "^1.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/npm/node_modules/retry": { - "version": "0.12.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm/node_modules/safe-buffer": { - "version": "5.2.1", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/safer-buffer": { - "version": "2.1.2", - "inBundle": true, - "license": "MIT", - "optional": true - }, - "node_modules/npm/node_modules/semver": { - "version": "7.5.4", - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/set-blocking": { - "version": "2.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/shebang-command": { - "version": "2.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/shebang-regex": { - "version": "3.0.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/signal-exit": { - "version": "4.1.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/sigstore": { - "version": "2.1.0", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.1.0", - "@sigstore/protobuf-specs": "^0.2.1", - "@sigstore/sign": "^2.1.0", - "@sigstore/tuf": "^2.1.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/smart-buffer": { - "version": "4.2.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks": { - "version": "2.7.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "^4.3.4", - "socks": "^2.7.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/spdx-correct": { - "version": "3.2.0", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-exceptions": { - "version": "2.3.0", - "inBundle": true, - "license": "CC-BY-3.0" - }, - "node_modules/npm/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.16", - "inBundle": true, - "license": "CC0-1.0" - }, - "node_modules/npm/node_modules/ssri": { - "version": "10.0.5", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/string_decoder": { - "version": "1.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/npm/node_modules/string-width": { - "version": "4.2.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/string-width/node_modules/strip-ansi": { - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "7.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/supports-color": { - "version": "9.4.0", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/npm/node_modules/tar": { - "version": "6.2.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "1.3.0", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/treeverse": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js": { - "version": "2.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/models": "2.0.0", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/unique-filename": { - "version": "3.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/unique-slug": { - "version": "4.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/util-deprecate": { - "version": "1.0.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "5.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "builtins": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/walk-up-path": { - "version": "3.0.1", - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/wcwidth": { - "version": "1.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/npm/node_modules/which": { - "version": "4.0.0", - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/which/node_modules/isexe": { - "version": "3.1.1", - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/npm/node_modules/wide-align": { - "version": "1.1.5", - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/npm/node_modules/wrap-ansi": { - "version": "8.1.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { - "version": "5.0.1", - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { - "version": "4.3.0", - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { - "version": "6.0.1", - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "inBundle": true, - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/write-file-atomic": { - "version": "5.0.1", - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/yallist": { - "version": "4.0.0", - "inBundle": true, - "license": "ISC" - }, - "node_modules/nwsapi": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz", - "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==", - "dev": true - }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/nyc/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/nyc/node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/object-is": { @@ -30302,6 +27552,7 @@ "version": "14.2.3", "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-14.2.3.tgz", "integrity": "sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==", + "peer": true, "dependencies": { "attr-accept": "^2.2.2", "file-selector": "^0.6.0", @@ -34182,10 +31433,7 @@ "version": "0.5.0", "license": "MIT", "dependencies": { - "@mantine/dropzone": "^6.0.21", - "@smile/react-front-kit-shared": "*", - "install": "^0.13.0", - "npm": "^10.2.0", + "@smile/react-front-kit-shared": "0.5.0", "pretty-bytes": "^6.1.1" }, "devDependencies": { @@ -34224,8 +31472,8 @@ "version": "0.5.0", "license": "MIT", "dependencies": { - "@smile/react-front-kit": "*", - "@smile/react-front-kit-shared": "*" + "@smile/react-front-kit": "0.5.0", + "@smile/react-front-kit-shared": "0.5.0" }, "devDependencies": { "@babel/preset-env": "^7.22.20", @@ -36382,8 +33630,8 @@ "version": "0.5.0", "license": "MIT", "dependencies": { - "@smile/react-front-kit": "*", - "@smile/react-front-kit-shared": "*" + "@smile/react-front-kit": "0.5.0", + "@smile/react-front-kit-shared": "0.5.0" }, "devDependencies": { "@babel/preset-env": "^7.22.20", diff --git a/packages/react-front-kit-dropzone/package.json b/packages/react-front-kit-dropzone/package.json index 7e3315af..715cb593 100644 --- a/packages/react-front-kit-dropzone/package.json +++ b/packages/react-front-kit-dropzone/package.json @@ -47,8 +47,8 @@ "prepublishOnly": "npm run build && node ../../scripts/prepublish.mjs" }, "dependencies": { - "@smile/react-front-kit": "*", - "@smile/react-front-kit-shared": "*" + "@smile/react-front-kit": "0.5.0", + "@smile/react-front-kit-shared": "0.5.0" }, "devDependencies": { "@babel/preset-env": "^7.22.20", diff --git a/packages/react-front-kit-table/package.json b/packages/react-front-kit-table/package.json index 7d9777ae..535b54c1 100644 --- a/packages/react-front-kit-table/package.json +++ b/packages/react-front-kit-table/package.json @@ -61,8 +61,8 @@ "prepublishOnly": "npm run build && node ../../scripts/prepublish.mjs" }, "dependencies": { - "@smile/react-front-kit": "*", - "@smile/react-front-kit-shared": "*" + "@smile/react-front-kit": "0.5.0", + "@smile/react-front-kit-shared": "0.5.0" }, "devDependencies": { "@babel/preset-env": "^7.22.20", diff --git a/packages/react-front-kit/package.json b/packages/react-front-kit/package.json index 970af391..649b57a2 100644 --- a/packages/react-front-kit/package.json +++ b/packages/react-front-kit/package.json @@ -62,10 +62,7 @@ "prepublishOnly": "npm run build && node ../../scripts/prepublish.mjs" }, "dependencies": { - "@mantine/dropzone": "^6.0.21", - "@smile/react-front-kit-shared": "*", - "install": "^0.13.0", - "npm": "^10.2.0", + "@smile/react-front-kit-shared": "0.5.0", "pretty-bytes": "^6.1.1" }, "devDependencies": { From a0aa52b8f10f264600704ec4aeee8a146d17cc9d Mon Sep 17 00:00:00 2001 From: Quentin Le Caignec <12102823+QuentinLeCaignec@users.noreply.github.com> Date: Wed, 29 Nov 2023 14:40:52 +0100 Subject: [PATCH 3/6] feat: added `defaultOpened` props to `CollapseButton` (#79) * feat: added `defaultOpened` props to `CollapseButton` --- .changeset/tender-buckets-attack.md | 5 +++++ .../src/Components/CollapseButton/CollapseButton.tsx | 6 ++++-- 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 .changeset/tender-buckets-attack.md diff --git a/.changeset/tender-buckets-attack.md b/.changeset/tender-buckets-attack.md new file mode 100644 index 00000000..a8c1b863 --- /dev/null +++ b/.changeset/tender-buckets-attack.md @@ -0,0 +1,5 @@ +--- +'@smile/react-front-kit': minor +--- + +Added `defaultOpened` prop to `CollapseButton` diff --git a/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.tsx b/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.tsx index f371f310..d888ab1e 100644 --- a/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.tsx +++ b/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.tsx @@ -22,6 +22,7 @@ export interface ICollapseButtonProps< component?: C; /** Additional props for the custom component */ componentProps?: ComponentPropsWithoutRef; + defaultOpened?: boolean; id?: T; isOpenOnSelect?: boolean; label?: ReactNode; @@ -36,10 +37,11 @@ export function CollapseButton< T extends number | string, C extends ElementType = 'button', >(props: ICollapseButtonProps): ReactElement { - const [opened, setOpened] = useState(false); + const { defaultOpened = false, ...rest } = props; + const [opened, setOpened] = useState(defaultOpened); return ( setOpened(!opened)} opened={opened} /> From 0e819eebaa3b8feeb9ce1d1ae1ac37358c383d2e Mon Sep 17 00:00:00 2001 From: Quentin Le Caignec <12102823+QuentinLeCaignec@users.noreply.github.com> Date: Fri, 8 Dec 2023 14:35:44 +0100 Subject: [PATCH 4/6] Feat/document list (#80) * feat: added `ActionBar`, `SelectableList` and `DocumentList` refactor: moved action bar from `ThumbnailGrid` into `ActionBar` refactor: updated `SearchPage` --- .changeset/brown-foxes-exist.md | 8 + package-lock.json | 3 + .../Components/ActionBar/ActionBar.mock.tsx | 58 ++ .../ActionBar/ActionBar.stories.tsx | 28 + .../Components/ActionBar/ActionBar.test.tsx | 11 + .../src/Components/ActionBar/ActionBar.tsx | 129 ++++ .../__snapshots__/ActionBar.test.tsx.snap | 90 +++ .../DocumentList/DocumentList.mock.tsx | 73 +++ .../DocumentList/DocumentList.stories.tsx | 26 + .../DocumentList/DocumentList.test.tsx | 23 + .../Components/DocumentList/DocumentList.tsx | 92 +++ .../__snapshots__/DocumentList.test.tsx.snap | 550 ++++++++++++++++++ .../SelectableList/SelectableList.mock.tsx | 70 +++ .../SelectableList/SelectableList.stories.tsx | 23 + .../SelectableList/SelectableList.test.tsx | 19 + .../SelectableList/SelectableList.tsx | 57 ++ .../SelectableList.test.tsx.snap | 464 +++++++++++++++ .../ThumbnailGrid/ThumbnailGrid.tsx | 122 +--- .../__snapshots__/ThumbnailGrid.test.tsx.snap | 2 +- packages/react-front-kit/src/index.tsx | 5 +- packages/storybook-pages/package.json | 3 + .../src/Pages/SearchResults/SearchResults.tsx | 127 ++-- .../storybook-pages/src/Pages/pages.mock.tsx | 86 ++- 23 files changed, 1887 insertions(+), 182 deletions(-) create mode 100644 .changeset/brown-foxes-exist.md create mode 100644 packages/react-front-kit/src/Components/ActionBar/ActionBar.mock.tsx create mode 100644 packages/react-front-kit/src/Components/ActionBar/ActionBar.stories.tsx create mode 100644 packages/react-front-kit/src/Components/ActionBar/ActionBar.test.tsx create mode 100644 packages/react-front-kit/src/Components/ActionBar/ActionBar.tsx create mode 100644 packages/react-front-kit/src/Components/ActionBar/__snapshots__/ActionBar.test.tsx.snap create mode 100644 packages/react-front-kit/src/Components/DocumentList/DocumentList.mock.tsx create mode 100644 packages/react-front-kit/src/Components/DocumentList/DocumentList.stories.tsx create mode 100644 packages/react-front-kit/src/Components/DocumentList/DocumentList.test.tsx create mode 100644 packages/react-front-kit/src/Components/DocumentList/DocumentList.tsx create mode 100644 packages/react-front-kit/src/Components/DocumentList/__snapshots__/DocumentList.test.tsx.snap create mode 100644 packages/react-front-kit/src/Components/SelectableList/SelectableList.mock.tsx create mode 100644 packages/react-front-kit/src/Components/SelectableList/SelectableList.stories.tsx create mode 100644 packages/react-front-kit/src/Components/SelectableList/SelectableList.test.tsx create mode 100644 packages/react-front-kit/src/Components/SelectableList/SelectableList.tsx create mode 100644 packages/react-front-kit/src/Components/SelectableList/__snapshots__/SelectableList.test.tsx.snap diff --git a/.changeset/brown-foxes-exist.md b/.changeset/brown-foxes-exist.md new file mode 100644 index 00000000..f8ce9dee --- /dev/null +++ b/.changeset/brown-foxes-exist.md @@ -0,0 +1,8 @@ +--- +'@smile/react-front-kit': minor +'storybook-pages': minor +--- + +Extracted action bar from `ThumbnailGrid` into new component. +Added `ActionBar`, `SelectableList` and `DocumentList` components. +Updated `SearchPage` example page. diff --git a/package-lock.json b/package-lock.json index 252d2bcb..917266b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35761,6 +35761,9 @@ "@smile/react-front-kit-shared": "*", "@smile/react-front-kit-table": "*" }, + "devDependencies": { + "@storybook/addon-actions": "^7.4.1" + }, "peerDependencies": { "@emotion/react": ">=11", "@mantine/core": "6", diff --git a/packages/react-front-kit/src/Components/ActionBar/ActionBar.mock.tsx b/packages/react-front-kit/src/Components/ActionBar/ActionBar.mock.tsx new file mode 100644 index 00000000..6a0e7365 --- /dev/null +++ b/packages/react-front-kit/src/Components/ActionBar/ActionBar.mock.tsx @@ -0,0 +1,58 @@ +import type { IActionBarProps } from './ActionBar'; +import type { IThumbnail, IThumbnailAction } from '../../types'; + +import { Trash } from '@phosphor-icons/react'; +import { FolderMove } from '@smile/react-front-kit-shared'; +import { action } from '@storybook/addon-actions'; + +export const actionBarActionsMock: IThumbnailAction[] = [ + { + icon: , + id: 'move', + isItemAction: false, + isMassAction: true, + label: 'Move in tree', + onAction: action('Move selected in tree'), + }, + { + color: 'red', + confirmModalProps: { + cancelLabel: 'Abort', + children:

Are you sure ?

, + confirmColor: 'red', + confirmLabel: 'Remove', + title: 'remove files ?', + }, + confirmation: true, + icon: , + id: 'delete', + isItemAction: false, + isMassAction: true, + label: 'Delete', + onAction: action('Delete selected'), + }, +]; + +export const actionBarSelectedMock: IThumbnail[] = [ + { + id: '1', + label: 'Label A', + }, + { + id: '2', + label: 'Label B', + }, + { + id: '3', + label: 'Label C', + }, +]; + +export const actionBarLabelMock = (elements: number): string => + `${elements} selected`; + +export const actionBarMock: IActionBarProps = { + actions: actionBarActionsMock, + selectedElements: actionBarSelectedMock, + selectedElementsLabel: actionBarLabelMock, +}; diff --git a/packages/react-front-kit/src/Components/ActionBar/ActionBar.stories.tsx b/packages/react-front-kit/src/Components/ActionBar/ActionBar.stories.tsx new file mode 100644 index 00000000..70de99e4 --- /dev/null +++ b/packages/react-front-kit/src/Components/ActionBar/ActionBar.stories.tsx @@ -0,0 +1,28 @@ +import type { IActionBarAction } from './ActionBar'; +import type { Meta, StoryObj } from '@storybook/react'; + +import { ActionBar as Cmp } from './ActionBar'; +import { + actionBarActionsMock, + actionBarLabelMock, + actionBarSelectedMock, +} from './ActionBar.mock'; + +const meta = { + component: Cmp, + tags: ['autodocs'], + title: '3-custom/Components/ActionBar', +} satisfies Meta; + +export default meta; +type IStory = StoryObj; + +export const ActionBar: IStory = { + args: { + actions: actionBarActionsMock as IActionBarAction< + Record + >[], + selectedElements: actionBarSelectedMock, + selectedElementsLabel: actionBarLabelMock, + }, +}; diff --git a/packages/react-front-kit/src/Components/ActionBar/ActionBar.test.tsx b/packages/react-front-kit/src/Components/ActionBar/ActionBar.test.tsx new file mode 100644 index 00000000..6b544421 --- /dev/null +++ b/packages/react-front-kit/src/Components/ActionBar/ActionBar.test.tsx @@ -0,0 +1,11 @@ +import { renderWithProviders } from '@smile/react-front-kit-shared/test-utils'; + +import { ActionBar } from './ActionBar'; +import { actionBarMock } from './ActionBar.mock'; + +describe('ActionBar', () => { + it('matches snapshot', () => { + const { container } = renderWithProviders(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-front-kit/src/Components/ActionBar/ActionBar.tsx b/packages/react-front-kit/src/Components/ActionBar/ActionBar.tsx new file mode 100644 index 00000000..30a360e5 --- /dev/null +++ b/packages/react-front-kit/src/Components/ActionBar/ActionBar.tsx @@ -0,0 +1,129 @@ +import type { GroupProps, ModalProps } from '@mantine/core'; +import type { Record } from '@phosphor-icons/react'; +import type { + IAction, + IActionConfirmModalProps, +} from '@smile/react-front-kit-shared'; +import type { ReactElement } from 'react'; + +import { Button, Group } from '@mantine/core'; +import { createStyles } from '@mantine/styles'; +import { useState } from 'react'; + +import { ConfirmModal } from '../ConfirmModal/ConfirmModal'; + +const useStyles = createStyles((theme) => ({ + actionBar: { + alignItems: 'center', + background: theme.fn.primaryColor(), + borderRadius: 4, + color: 'white', + display: 'inline-flex', + justifyContent: 'space-between', + padding: '16px 24px', + width: '100%', + }, +})); + +export type IActionBarAction> = IAction< + Data | Data[] +>; + +export interface IActionBarProps> + extends GroupProps { + actions?: IActionBarAction[]; + modalProps?: Omit; + selectedElements: Data[]; + selectedElementsLabel?: (selectedElements: number) => string; +} + +export function ActionBar>( + props: IActionBarProps, +): ReactElement { + const { + actions, + modalProps, + selectedElements, + selectedElementsLabel = (selectedElements: number) => + `${selectedElements} file(s) selected`, + ...groupProps + } = props; + const [confirmAction, setConfirmAction] = useState | null>(null); + const numberOfSelectedElements = selectedElements.length; + + const { classes } = useStyles(); + + function setModal(action: IAction): void { + setConfirmAction({ + cancelColor: action.confirmModalProps?.cancelColor, + cancelLabel: action.confirmModalProps?.cancelLabel, + children: action.confirmModalProps?.children, + confirmColor: action.confirmModalProps?.confirmColor, + confirmLabel: action.confirmModalProps?.confirmLabel, + onConfirm: () => action.onAction?.(selectedElements), + title: action.confirmModalProps?.title, + }); + } + + function clearConfirmAction(): void { + setConfirmAction(null); + } + + function handleClose(): void { + clearConfirmAction(); + } + + function handleModalButton(onAction?: (item: Data[]) => void): void { + onAction?.(selectedElements); + handleClose(); + } + + function handleGridAction(action: IAction): void { + if (action.confirmation) { + setModal(action); + } else { + action.onAction?.(selectedElements); + } + } + + return ( + <> +
+ {selectedElementsLabel(numberOfSelectedElements)} + {actions && actions.length > 0 ? ( + + {actions.map((action) => ( + + ))} + + ) : null} +
+ handleModalButton(confirmAction?.onCancel)} + onClose={handleClose} + onConfirm={() => handleModalButton(confirmAction?.onConfirm)} + opened={Boolean(confirmAction)} + {...modalProps} + > + {confirmAction?.children} + + + ); +} diff --git a/packages/react-front-kit/src/Components/ActionBar/__snapshots__/ActionBar.test.tsx.snap b/packages/react-front-kit/src/Components/ActionBar/__snapshots__/ActionBar.test.tsx.snap new file mode 100644 index 00000000..05e1c4a0 --- /dev/null +++ b/packages/react-front-kit/src/Components/ActionBar/__snapshots__/ActionBar.test.tsx.snap @@ -0,0 +1,90 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ActionBar matches snapshot 1`] = ` +
+
+ + 3 selected + +
+ + +
+
+
+`; diff --git a/packages/react-front-kit/src/Components/DocumentList/DocumentList.mock.tsx b/packages/react-front-kit/src/Components/DocumentList/DocumentList.mock.tsx new file mode 100644 index 00000000..c0316974 --- /dev/null +++ b/packages/react-front-kit/src/Components/DocumentList/DocumentList.mock.tsx @@ -0,0 +1,73 @@ +import type { IDocument } from '../../../dist'; + +import { Button, Space } from '@mantine/core'; +import { DownloadSimple } from '@phosphor-icons/react'; + +export const documentsMock: IDocument[] = [ + { + author: 'Author Name', + content: ( + <> +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + minim veniam, quis nostrud exercitation ullamco laboris nisi ut +

+ + + ), + date: 'Published on December 24, 2023', + iconType: 'PDF', + id: 1, + path: '(Customer > 567890456 > Invoices)', + title: 'Random_File.PDF', + }, + { + author: 'Author Name', + content: ( + <> +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + minim veniam, quis nostrud exercitation ullamco laboris nisi ut +

+ + + ), + date: 'Published on December 24, 2023', + iconType: 'PPT', + id: 2, + path: '(Customer > 567890456 > Invoices)', + title: 'Presentation.PPT', + }, + { + author: 'Author Name', + content: ( + <> +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do + eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad + minim veniam, quis nostrud exercitation ullamco laboris nisi ut +

+ + + ), + date: 'Published on December 24, 2023', + iconType: 'PDF', + id: 3, + path: '(Customer > 567890456 > Invoices)', + title: 'Other_random_File.PDF', + }, +]; diff --git a/packages/react-front-kit/src/Components/DocumentList/DocumentList.stories.tsx b/packages/react-front-kit/src/Components/DocumentList/DocumentList.stories.tsx new file mode 100644 index 00000000..01064d05 --- /dev/null +++ b/packages/react-front-kit/src/Components/DocumentList/DocumentList.stories.tsx @@ -0,0 +1,26 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { action } from '@storybook/addon-actions'; + +import { actionBarActionsMock } from '../ActionBar/ActionBar.mock'; + +import { DocumentList as Cmp } from './DocumentList'; +import { documentsMock } from './DocumentList.mock'; + +const meta = { + component: Cmp, + tags: ['autodocs'], + title: '3-custom/Components/DocumentList', +} satisfies Meta; + +export default meta; +type IStory = StoryObj; + +export const DocumentList: IStory = { + args: { + actions: actionBarActionsMock, + documents: documentsMock, + onDocumentSelected: action('Document selected'), + selectedDocuments: [documentsMock[1]], + }, +}; diff --git a/packages/react-front-kit/src/Components/DocumentList/DocumentList.test.tsx b/packages/react-front-kit/src/Components/DocumentList/DocumentList.test.tsx new file mode 100644 index 00000000..2cb5e940 --- /dev/null +++ b/packages/react-front-kit/src/Components/DocumentList/DocumentList.test.tsx @@ -0,0 +1,23 @@ +import { renderWithProviders } from '@smile/react-front-kit-shared/test-utils'; + +import { actionBarActionsMock } from '../ActionBar/ActionBar.mock'; + +import { DocumentList } from './DocumentList'; +import { documentsMock } from './DocumentList.mock'; + +describe('DocumentList', () => { + beforeEach(() => { + // Prevent mantine random ID + Math.random = () => 0.42; + }); + it('matches snapshot', () => { + const { container } = renderWithProviders( + , + ); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-front-kit/src/Components/DocumentList/DocumentList.tsx b/packages/react-front-kit/src/Components/DocumentList/DocumentList.tsx new file mode 100644 index 00000000..fd92273f --- /dev/null +++ b/packages/react-front-kit/src/Components/DocumentList/DocumentList.tsx @@ -0,0 +1,92 @@ +import type { IActionBarAction, IActionBarProps } from '../ActionBar/ActionBar'; +import type { ISelectableListProps } from '../SelectableList/SelectableList'; +import type { ReactElement, ReactNode } from 'react'; + +import { isNotNullNorEmpty } from '@smile/react-front-kit-shared'; +import { useMemo } from 'react'; + +import { ActionBar } from '../ActionBar/ActionBar'; +import { DocumentCard } from '../DocumentCard/DocumentCard'; +import { SelectableList } from '../SelectableList/SelectableList'; + +export interface IDocument extends Record { + author?: string; + content?: ReactNode; + date?: string; + iconType?: string; + id: number | string; + path?: string; + title?: string; +} + +export interface IDocumentListProps + extends Omit< + ISelectableListProps, + 'children' | 'onSelectChange' | 'selectedIndexes' + > { + actionBarProps?: Omit< + IActionBarProps, + 'actions' | 'selectedElements' + >; + actions?: IActionBarAction[]; + documents: IDocument[]; + onDocumentSelected?: (document: IDocument, isSelected: boolean) => void; + selectedDocuments: IDocument[]; +} + +export function DocumentList(props: IDocumentListProps): ReactElement { + const { + actionBarProps, + actions, + documents, + selectedDocuments, + onDocumentSelected, + ...selectableListProps + } = props; + const selectedIndexes = useMemo( + () => + documents + .map((document, i) => + selectedDocuments.map((selected) => selected.id).includes(document.id) + ? i + : null, + ) + .filter(isNotNullNorEmpty), + [documents, selectedDocuments], + ); + + function handleSelectChange(index: number, isSelected: boolean): void { + onDocumentSelected?.(documents[index], isSelected); + } + + return ( +
+ {selectedDocuments.length > 0 && ( + + actions={actions} + selectedElements={selectedDocuments} + {...actionBarProps} + /> + )} + + {documents.map((document) => ( + + {document.content} + + ))} + +
+ ); +} diff --git a/packages/react-front-kit/src/Components/DocumentList/__snapshots__/DocumentList.test.tsx.snap b/packages/react-front-kit/src/Components/DocumentList/__snapshots__/DocumentList.test.tsx.snap new file mode 100644 index 00000000..38c6f1d9 --- /dev/null +++ b/packages/react-front-kit/src/Components/DocumentList/__snapshots__/DocumentList.test.tsx.snap @@ -0,0 +1,550 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DocumentList matches snapshot 1`] = ` +
+
+
+ + 1 file(s) selected + +
+ + +
+
+
+
+
+
+
+ + + + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ + + +
+
+
+ + Random_File.PDF + + + (Customer > 567890456 > Invoices) + +
+
+ + Published on December 24, 2023 + + + - + + + Author Name + +
+
+
+
+
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut +

+ +
+
+
+
+
+
+
+
+ + + + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ + + +
+
+
+ + Presentation.PPT + + + (Customer > 567890456 > Invoices) + +
+
+ + Published on December 24, 2023 + + + - + + + Author Name + +
+
+
+
+
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut +

+ +
+
+
+
+
+
+
+
+ + + + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ + + +
+
+
+ + Other_random_File.PDF + + + (Customer > 567890456 > Invoices) + +
+
+ + Published on December 24, 2023 + + + - + + + Author Name + +
+
+
+
+
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut +

+ +
+
+
+
+
+
+
+`; diff --git a/packages/react-front-kit/src/Components/SelectableList/SelectableList.mock.tsx b/packages/react-front-kit/src/Components/SelectableList/SelectableList.mock.tsx new file mode 100644 index 00000000..c19c9ee1 --- /dev/null +++ b/packages/react-front-kit/src/Components/SelectableList/SelectableList.mock.tsx @@ -0,0 +1,70 @@ +import { Button, Space } from '@mantine/core'; +import { DownloadSimple } from '@phosphor-icons/react'; + +import { DocumentCard } from '../DocumentCard/DocumentCard'; + +export const selectableListElementsMock = [ + + <> +

+ Ceci est une description faite pour cette facture et ajoutée par le + créateur lors de l’import du document dans la GED, en l’absence de + description cet espace est laissé vide... +

+ + +
, + + <> +

+ Ceci est une description faite pour cette facture et ajoutée par le + créateur lors de l’import du document dans la GED, en l’absence de + description cet espace est laissé vide... +

+ + +
, + + <> +

+ Ceci est une description faite pour cette facture et ajoutée par le + créateur lors de l’import du document dans la GED, en l’absence de + description cet espace est laissé vide... +

+ + +
, +]; diff --git a/packages/react-front-kit/src/Components/SelectableList/SelectableList.stories.tsx b/packages/react-front-kit/src/Components/SelectableList/SelectableList.stories.tsx new file mode 100644 index 00000000..59f14cf2 --- /dev/null +++ b/packages/react-front-kit/src/Components/SelectableList/SelectableList.stories.tsx @@ -0,0 +1,23 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { action } from '@storybook/addon-actions'; + +import { SelectableList as Cmp } from './SelectableList'; +import { selectableListElementsMock } from './SelectableList.mock'; + +const meta = { + component: Cmp, + tags: ['autodocs'], + title: '3-custom/Components/SelectableList', +} satisfies Meta; + +export default meta; +type IStory = StoryObj; + +export const SelectableList: IStory = { + args: { + children: selectableListElementsMock, + onSelectChange: action('Element selected'), + selectedIndexes: [1, 2], + }, +}; diff --git a/packages/react-front-kit/src/Components/SelectableList/SelectableList.test.tsx b/packages/react-front-kit/src/Components/SelectableList/SelectableList.test.tsx new file mode 100644 index 00000000..bfdae744 --- /dev/null +++ b/packages/react-front-kit/src/Components/SelectableList/SelectableList.test.tsx @@ -0,0 +1,19 @@ +import { renderWithProviders } from '@smile/react-front-kit-shared/test-utils'; + +import { SelectableList } from './SelectableList'; +import { selectableListElementsMock } from './SelectableList.mock'; + +describe('SelectableList', () => { + beforeEach(() => { + // Prevent mantine random ID + Math.random = () => 0.42; + }); + it('matches snapshot', () => { + const { container } = renderWithProviders( + + {selectableListElementsMock} + , + ); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-front-kit/src/Components/SelectableList/SelectableList.tsx b/packages/react-front-kit/src/Components/SelectableList/SelectableList.tsx new file mode 100644 index 00000000..5db4e4f6 --- /dev/null +++ b/packages/react-front-kit/src/Components/SelectableList/SelectableList.tsx @@ -0,0 +1,57 @@ +import type { StackProps } from '@mantine/core'; +import type { ReactElement } from 'react'; + +import { Checkbox, Group, Stack } from '@mantine/core'; +import { createStyles } from '@mantine/styles'; + +const useStyles = createStyles(() => ({ + element: { + ':not(:last-child):after': { + border: '1px #e9ecef solid', + bottom: '-41px', + content: '""', + position: 'absolute', + width: '100%', + }, + position: 'relative', + }, +})); + +export interface ISelectableListProps extends StackProps { + children: ReactElement[]; + onSelectChange?: (index: number, isSelected: boolean) => void; + selectedIndexes?: number[]; +} + +export function SelectableList(props: ISelectableListProps): ReactElement { + const { + children, + onSelectChange, + selectedIndexes = [], + ...stackProps + } = props; + + const { classes } = useStyles(); + + return ( + + {children.map((element, index) => ( + // eslint-disable-next-line react/no-array-index-key + + onSelectChange?.(index, e.currentTarget.checked)} + radius={2} + size={16} + /> + {element} + + ))} + + ); +} diff --git a/packages/react-front-kit/src/Components/SelectableList/__snapshots__/SelectableList.test.tsx.snap b/packages/react-front-kit/src/Components/SelectableList/__snapshots__/SelectableList.test.tsx.snap new file mode 100644 index 00000000..fca567e1 --- /dev/null +++ b/packages/react-front-kit/src/Components/SelectableList/__snapshots__/SelectableList.test.tsx.snap @@ -0,0 +1,464 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`SelectableList matches snapshot 1`] = ` +
+
+
+
+
+
+ + + + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ + + +
+
+
+ + Random_File.PDF + + + (Customer > 567890456 > Invoices) + +
+
+ + Published on December 24, 2023 + + + - + + + Aline Dupon + +
+
+
+
+
+

+ Ceci est une description faite pour cette facture et ajoutée par le créateur lors de l’import du document dans la GED, en l’absence de description cet espace est laissé vide... +

+ +
+
+
+
+
+
+
+
+ + + + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ + + +
+
+
+ + Presentation.PPT + + + (Customer > 567890456 > Invoices) + +
+
+ + Published on December 24, 2023 + + + - + + + Julien Dominique + +
+
+
+
+
+

+ Ceci est une description faite pour cette facture et ajoutée par le créateur lors de l’import du document dans la GED, en l’absence de description cet espace est laissé vide... +

+ +
+
+
+
+
+
+
+
+ + + + +
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+ + + +
+
+
+ + Other_random_File.PDF + + + (Customer > 567890456 > Invoices) + +
+
+ + Published on December 24, 2023 + + + - + + + Mohamed Aldri + +
+
+
+
+
+

+ Ceci est une description faite pour cette facture et ajoutée par le créateur lors de l’import du document dans la GED, en l’absence de description cet espace est laissé vide... +

+ +
+
+
+
+
+
+`; diff --git a/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.tsx b/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.tsx index 5999dea8..682e3127 100644 --- a/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.tsx +++ b/packages/react-front-kit/src/Components/ThumbnailGrid/ThumbnailGrid.tsx @@ -2,39 +2,26 @@ import type { IThumbnail, IThumbnailAction } from '../../types'; import type { SimpleGridProps } from '@mantine/core'; -import type { IActionConfirmModalProps } from '@smile/react-front-kit-shared'; import type { ReactElement } from 'react'; -import { Button, Group, SimpleGrid } from '@mantine/core'; +import { SimpleGrid } from '@mantine/core'; import { createStyles } from '@mantine/styles'; -import { useState } from 'react'; -import { ConfirmModal } from '../ConfirmModal/ConfirmModal'; +import { ActionBar } from '../ActionBar/ActionBar'; import { Thumbnail } from '../Thumbnail/Thumbnail'; -const useStyles = createStyles((theme) => ({ +const useStyles = createStyles(() => ({ container: { display: 'flex', flexDirection: 'column', gap: 24, }, - topBar: { - alignItems: 'center', - background: theme.fn.primaryColor(), - borderRadius: 4, - color: 'white', - display: 'inline-flex', - justifyContent: 'space-between', - padding: '16px 24px', - }, })); function defaultSelectedElementsText(n: number): string { return `${n} selected file${n > 1 ? 's' : ''}`; } -type IGridActionConfirmModalProps = IActionConfirmModalProps; - export interface IThumbnailGridProps extends SimpleGridProps { actions?: IThumbnailAction[]; onThumbnailClick?: (item: IThumbnail, index: number) => void; @@ -54,8 +41,6 @@ export function ThumbnailGrid(props: IThumbnailGridProps): ReactElement { const selectedElements = thumbnails.filter((thumbnail) => thumbnail.selected); const numberOfSelectedElements = selectedElements.length; - const [confirmAction, setConfirmAction] = - useState(null); const massActions = actions.filter(({ isMassAction }) => isMassAction); const itemActions = actions.filter(({ isItemAction = true }) => isItemAction); @@ -65,88 +50,25 @@ export function ThumbnailGrid(props: IThumbnailGridProps): ReactElement { onThumbnailClick?.(thumbnails[index], index); } - function setModal(action: IThumbnailAction): void { - setConfirmAction({ - cancelColor: action.confirmModalProps?.cancelColor, - cancelLabel: action.confirmModalProps?.cancelLabel, - children: action.confirmModalProps?.children, - confirmColor: action.confirmModalProps?.confirmColor, - confirmLabel: action.confirmModalProps?.confirmLabel, - onConfirm: () => action.onAction?.(selectedElements), - title: action.confirmModalProps?.title, - }); - } - - function handleGridAction(action: IThumbnailAction): void { - if (action.confirmation) { - setModal(action); - } else { - action.onAction?.(selectedElements); - } - } - - function clearConfirmAction(): void { - setConfirmAction(null); - } - - function handleClose(): void { - clearConfirmAction(); - } - - function handleModalButton(onAction?: (item: IThumbnail[]) => void): void { - onAction?.(selectedElements); - handleClose(); - } - return ( - <> -
- {numberOfSelectedElements > 0 && ( -
- {selectedElementsText(numberOfSelectedElements)} - {massActions.length > 0 && ( - - {massActions.map((action) => ( - - ))} - - )} -
- )} - - {thumbnails.map((thumbnail, index) => ( - handleSelect(index)} - {...thumbnail} - /> - ))} - -
- handleModalButton(confirmAction?.onCancel)} - onClose={handleClose} - onConfirm={() => handleModalButton(confirmAction?.onConfirm)} - opened={Boolean(confirmAction)} - > - {confirmAction?.children} - - +
+ {numberOfSelectedElements > 0 && ( + + actions={massActions} + selectedElements={selectedElements} + selectedElementsLabel={selectedElementsText} + /> + )} + + {thumbnails.map((thumbnail, index) => ( + handleSelect(index)} + {...thumbnail} + /> + ))} + +
); } diff --git a/packages/react-front-kit/src/Components/ThumbnailGrid/__snapshots__/ThumbnailGrid.test.tsx.snap b/packages/react-front-kit/src/Components/ThumbnailGrid/__snapshots__/ThumbnailGrid.test.tsx.snap index a6678da3..e3ca7158 100644 --- a/packages/react-front-kit/src/Components/ThumbnailGrid/__snapshots__/ThumbnailGrid.test.tsx.snap +++ b/packages/react-front-kit/src/Components/ThumbnailGrid/__snapshots__/ThumbnailGrid.test.tsx.snap @@ -6,7 +6,7 @@ exports[`ThumbnailGrid matches snapshot 1`] = ` class="mantine-1skbp38" >
1 selected file diff --git a/packages/react-front-kit/src/index.tsx b/packages/react-front-kit/src/index.tsx index a7902d96..7d5ca2b0 100644 --- a/packages/react-front-kit/src/index.tsx +++ b/packages/react-front-kit/src/index.tsx @@ -1,14 +1,16 @@ /* eslint-disable react-refresh/only-export-components */ export * from '@smile/react-front-kit-shared'; // component exports -export * from './Components/Filters/Filters'; +export * from './Components/ActionBar/ActionBar'; export * from './Components/BitConverter/BitConverter'; export * from './Components/Breadcrumbs/Breadcrumbs'; export * from './Components/CollapseButton/CollapseButtonControlled'; export * from './Components/CollapseButton/CollapseButton'; export * from './Components/ConfirmModal/ConfirmModal'; export * from './Components/DocumentCard/DocumentCard'; +export * from './Components/DocumentList/DocumentList'; export * from './Components/DropdownButton/DropdownButton'; +export * from './Components/Filters/Filters'; export * from './Components/Header/Header'; export * from './Components/HeaderSearch/HeaderSearch'; export * from './Components/InfoCard/InfoCard'; @@ -16,6 +18,7 @@ export * from './Components/InfoCard/Motif'; export * from './Components/Pagination/Pagination'; export * from './Components/ResponsiveTabs/ResponsiveTabs'; export * from './Components/SearchBar/SearchBar'; +export * from './Components/SelectableList/SelectableList'; export * from './Components/SidebarMenu/SidebarMenu'; export * from './Components/SwitchableView/SwitchableView'; export * from './Components/Thumbnail/Thumbnail'; diff --git a/packages/storybook-pages/package.json b/packages/storybook-pages/package.json index 317512bc..ae42faa2 100644 --- a/packages/storybook-pages/package.json +++ b/packages/storybook-pages/package.json @@ -12,6 +12,9 @@ "@smile/react-front-kit-shared": "*", "@smile/react-front-kit-table": "*" }, + "devDependencies": { + "@storybook/addon-actions": "^7.4.1" + }, "peerDependencies": { "@emotion/react": ">=11", "@mantine/core": "6", diff --git a/packages/storybook-pages/src/Pages/SearchResults/SearchResults.tsx b/packages/storybook-pages/src/Pages/SearchResults/SearchResults.tsx index f760a85d..b70cf8ad 100644 --- a/packages/storybook-pages/src/Pages/SearchResults/SearchResults.tsx +++ b/packages/storybook-pages/src/Pages/SearchResults/SearchResults.tsx @@ -1,23 +1,20 @@ 'use client'; +import type { IDocument } from '@smile/react-front-kit'; import type { ReactElement } from 'react'; import { AppShell, Box, - Button, - Divider, Flex, Paper, Select, - Space, - Stack, createStyles, rem, } from '@mantine/core'; -import { CaretDown, DownloadSimple } from '@phosphor-icons/react'; +import { CaretDown } from '@phosphor-icons/react'; import { - DocumentCard, + DocumentList, FoldableColumnLayout, Header, Motif, @@ -30,7 +27,13 @@ import { } from '@smile/react-front-kit-shared'; import { useState } from 'react'; -import { headerContent, headerLeft, headerRight } from '../pages.mock'; +import { + headerContent, + headerLeft, + headerRight, + searchActions, + searchDocuments, +} from '../pages.mock'; export interface IOption { label: string; @@ -121,8 +124,32 @@ export function SearchResults(): ReactElement { const [activeSorting, setActiveSorting] = useState( sortingOptions[0]?.value, ); - const totalPages = Math.ceil(typeFilteredResults / rowsPerPage); + // Documents + const [selectedDocuments, setSelectedDocuments] = useState([]); + + function handleDocumentSelected( + selectedDocument: IDocument, + isSelected: boolean, + ): void { + const newSelectedDocuments = [...selectedDocuments]; + if ( + newSelectedDocuments + .map((document) => document.id) + .includes(selectedDocument.id) && + !isSelected + ) { + delete newSelectedDocuments[ + newSelectedDocuments.findIndex( + (document) => document.id === selectedDocument.id, + ) + ]; + } else { + newSelectedDocuments.push(selectedDocument); + } + setSelectedDocuments(newSelectedDocuments.filter(isNotNullNorEmpty)); + } + const { classes } = useStyles(); return ( @@ -203,77 +230,19 @@ export function SearchResults(): ReactElement { } topBlockTheme={{ ...secondaryTheme, colorScheme: 'dark' }} > - - - - - <> -

- Ceci est une description faite pour cette facture et ajoutée - par le créateur lors de l’import du document dans la GED, en - l’absence de description cet espace est laissé vide... -

- - -
- - - - - <> -

- Ceci est une description faite pour cette facture et ajoutée - par le créateur lors de l’import du document dans la GED, en - l’absence de description cet espace est laissé vide... -

- - -
- - - - - <> -

- Ceci est une description faite pour cette facture et ajoutée - par le créateur lors de l’import du document dans la GED, en - l’absence de description cet espace est laissé vide... -

- - -
- -
+ + + `${n} fichier${n > 1 ? 's' : ''} sélectionné${ + n > 1 ? 's' : '' + }`, + }} + actions={searchActions} + documents={searchDocuments} + onDocumentSelected={handleDocumentSelected} + selectedDocuments={selectedDocuments} + /> @@ -35,3 +39,83 @@ export const headerRight = ( /> ); + +export const searchDocuments: IDocument[] = [ + { + author: 'Aline Dupon', + content: ( + <> +

+ Ceci est une description faite pour cette facture et ajoutée par le + créateur lors de l’import du document dans la GED, en l’absence de + description cet espace est laissé vide... +

+ + + ), + date: 'Published on December 24, 2023', + iconType: 'PDF', + id: 1, + path: '(Customer > 567890456 > Invoices)', + title: 'Random_File.PDF', + }, + { + author: 'Julien Dominique', + content: ( + <> +

+ Ceci est une description faite pour cette facture et ajoutée par le + créateur lors de l’import du document dans la GED, en l’absence de + description cet espace est laissé vide... +

+ + + ), + date: 'Published on December 24, 2023', + iconType: 'PPT', + id: 2, + path: '(Customer > 567890456 > Invoices)', + title: 'Presentation.PPT', + }, + { + author: 'Mohamed Aldri', + content: ( + <> +

+ Ceci est une description faite pour cette facture et ajoutée par le + créateur lors de l’import du document dans la GED, en l’absence de + description cet espace est laissé vide... +

+ + + ), + date: 'Published on December 24, 2023', + iconType: 'PDF', + id: 3, + path: '(Customer > 567890456 > Invoices)', + title: 'Other_random_File.PDF', + }, +]; + +export const searchActions: IActionBarAction[] = [ + { + icon: , + id: 'download', + isItemAction: false, + isMassAction: true, + label: 'Télécharger', + onAction: action('Download files'), + }, +]; From 7f276b27e9c2ca2b746ad0f39deaee49cbf8bb90 Mon Sep 17 00:00:00 2001 From: vapersmile <120370047+vapersmile@users.noreply.github.com> Date: Fri, 8 Dec 2023 15:49:57 +0100 Subject: [PATCH 5/6] Feat/filters (#81) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(redmine 1245005): add filters component in searchResultPage * feat(redmine 1245005): add number counter fo actif filters * feat(redmine 1245005): add indentation without line style for collapseButton * feat(redmine 1245005): add new fonctionality Button remove location and active filters collapse * feat(redmine 1245005): add button close all + open all + add function getFiltersMenuId * feat(redmine 1245005): add line for between button open and close * feat(redmine 1245005): use flat() for collapse menu active * feat(redmine 1245005): modify story and rename Fiters to filtersBar component * feat(redmine 1245005): modify story and rename Fiters to filtersBar component * feat(redmine 1245005): add dynamique data for search results * feat(redmine 1245005): fix no-wrap error for badge in filters active section * feat(redmine 1245005): add filters numbers active value on searchbar * feat(redmine 1245005): fixe test mantine ids test error * feat(redmine 1245005): fixe intégration error * feat(redmine 1245005): fixe pr review by Quentin * feat(redmine 1245005): fixe pr review by Quentin * feat(redmine 1245005): fix pr conflicts --- .changeset/slow-rivers-confess.md | 6 + .vscode/launch.json | 15 + package-lock.json | 1 + .../CollapseButton/CollapseButton.stories.tsx | 9 +- .../CollapseButton/CollapseButton.tsx | 2 +- .../CollapseButtonControlled.tsx | 29 +- .../Components/Filters/Filters.stories.tsx | 38 -- .../src/Components/Filters/Filters.test.tsx | 10 - .../src/Components/Filters/Filters.tsx | 88 --- .../SidebarFilterMenu.mock.tsx | 60 -- .../__snapshots__/Filters.test.tsx.snap | 83 --- .../FiltersBar/FiltersBar.stories.tsx | 38 ++ .../FiltersBar.style.tsx} | 42 +- .../Components/FiltersBar/FiltersBar.test.tsx | 21 + .../src/Components/FiltersBar/FiltersBar.tsx | 219 +++++++ .../Components/FiltersBar/FitlersBar.mock.tsx | 26 + .../SidebarFilterMenu.mock.tsx | 89 +++ .../SidebarFilterMenu.style.tsx | 0 .../SidebarFilterMenu.test.tsx | 0 .../SidebarFilterMenu/SidebarFilterMenu.tsx | 33 +- .../SidebarFilterMenu.test.tsx.snap | 0 .../__snapshots__/FiltersBar.test.tsx.snap | 587 ++++++++++++++++++ .../Components/SidebarMenu/SidebarMenu.tsx | 2 +- .../__snapshots__/SidebarMenu.test.tsx.snap | 4 +- packages/react-front-kit/src/index.tsx | 2 +- packages/storybook-pages/package.json | 1 + .../SearchResults/SearchResults.style.tsx | 22 + .../src/Pages/SearchResults/SearchResults.tsx | 322 ++++++++-- 28 files changed, 1376 insertions(+), 373 deletions(-) create mode 100644 .changeset/slow-rivers-confess.md create mode 100644 .vscode/launch.json delete mode 100644 packages/react-front-kit/src/Components/Filters/Filters.stories.tsx delete mode 100644 packages/react-front-kit/src/Components/Filters/Filters.test.tsx delete mode 100644 packages/react-front-kit/src/Components/Filters/Filters.tsx delete mode 100644 packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.mock.tsx delete mode 100644 packages/react-front-kit/src/Components/Filters/__snapshots__/Filters.test.tsx.snap create mode 100644 packages/react-front-kit/src/Components/FiltersBar/FiltersBar.stories.tsx rename packages/react-front-kit/src/Components/{Filters/Filters.style.tsx => FiltersBar/FiltersBar.style.tsx} (55%) create mode 100644 packages/react-front-kit/src/Components/FiltersBar/FiltersBar.test.tsx create mode 100644 packages/react-front-kit/src/Components/FiltersBar/FiltersBar.tsx create mode 100644 packages/react-front-kit/src/Components/FiltersBar/FitlersBar.mock.tsx create mode 100644 packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.mock.tsx rename packages/react-front-kit/src/Components/{Filters => FiltersBar}/SidebarFilterMenu/SidebarFilterMenu.style.tsx (100%) rename packages/react-front-kit/src/Components/{Filters => FiltersBar}/SidebarFilterMenu/SidebarFilterMenu.test.tsx (100%) rename packages/react-front-kit/src/Components/{Filters => FiltersBar}/SidebarFilterMenu/SidebarFilterMenu.tsx (84%) rename packages/react-front-kit/src/Components/{Filters => FiltersBar}/SidebarFilterMenu/__snapshots__/SidebarFilterMenu.test.tsx.snap (100%) create mode 100644 packages/react-front-kit/src/Components/FiltersBar/__snapshots__/FiltersBar.test.tsx.snap create mode 100644 packages/storybook-pages/src/Pages/SearchResults/SearchResults.style.tsx diff --git a/.changeset/slow-rivers-confess.md b/.changeset/slow-rivers-confess.md new file mode 100644 index 00000000..2c7d63d1 --- /dev/null +++ b/.changeset/slow-rivers-confess.md @@ -0,0 +1,6 @@ +--- +'@smile/react-front-kit': minor +'storybook-pages': minor +--- + +Add the filtersBar component and add it to the searchResult page diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..88e079b3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Utilisez IntelliSense pour en savoir plus sur les attributs possibles. + // Pointez pour afficher la description des attributs existants. + // Pour plus d'informations, visitez : https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Launch Chrome against localhost", + "url": "http://localhost:8080", + "webRoot": "${workspaceFolder}" + } + ] +} diff --git a/package-lock.json b/package-lock.json index 917266b0..f7364854 100644 --- a/package-lock.json +++ b/package-lock.json @@ -35767,6 +35767,7 @@ "peerDependencies": { "@emotion/react": ">=11", "@mantine/core": "6", + "@mantine/dates": "6", "@mantine/hooks": "6", "@mantine/styles": "6", "@phosphor-icons/react": ">=2", diff --git a/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.stories.tsx b/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.stories.tsx index 975d7675..7a312095 100644 --- a/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.stories.tsx +++ b/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.stories.tsx @@ -14,6 +14,10 @@ const meta = { id: { control: 'text', }, + indentation: { + control: 'select', + options: ['line', 'simple'], + }, label: { control: 'text', }, @@ -49,11 +53,11 @@ export const CollapseButton: IStory = { children, fullWidth: true, id: '', + indentation: 'simple', isOpenOnSelect: false, label: 'Home', leftIcon: iconsElements.HouseLine, level: 0, - line: false, radius: 0, selected: false, variant: 'white', @@ -80,11 +84,11 @@ export const Nested: IStory = { ), fullWidth: true, id: '', + indentation: 'line', isOpenOnSelect: false, label: 'Pull Requests', leftIcon: iconsElements.User, level: 0, - line: true, radius: 0, selected: false, }, @@ -101,7 +105,6 @@ export const WithLink: IStory = { label: 'Home', leftIcon: iconsElements.HouseLine, level: 0, - line: false, radius: 0, selected: false, variant: 'white', diff --git a/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.tsx b/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.tsx index d888ab1e..03509fa2 100644 --- a/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.tsx +++ b/packages/react-front-kit/src/Components/CollapseButton/CollapseButton.tsx @@ -24,10 +24,10 @@ export interface ICollapseButtonProps< componentProps?: ComponentPropsWithoutRef; defaultOpened?: boolean; id?: T; + indentation?: 'line' | 'simple'; isOpenOnSelect?: boolean; label?: ReactNode; level?: number; - line?: boolean; onSelect?: (id?: T) => void; selected?: boolean; } diff --git a/packages/react-front-kit/src/Components/CollapseButton/CollapseButtonControlled.tsx b/packages/react-front-kit/src/Components/CollapseButton/CollapseButtonControlled.tsx index 101099a0..212efed7 100644 --- a/packages/react-front-kit/src/Components/CollapseButton/CollapseButtonControlled.tsx +++ b/packages/react-front-kit/src/Components/CollapseButton/CollapseButtonControlled.tsx @@ -27,6 +27,16 @@ const useStyles = createStyles((theme) => ({ background: theme.colorScheme === 'light' ? theme.white : theme.colors.dark[7], }, + indentationLine: { + borderLeft: + theme.colorScheme === 'light' + ? `1px solid ${theme.colors.gray[1]}` + : `1px solid ${theme.colors.gray[8]}`, + marginLeft: 30, + }, + indentationSimple: { + paddingLeft: 30, + }, label: { color: theme.colorScheme === 'light' @@ -41,13 +51,6 @@ const useStyles = createStyles((theme) => ({ labelLevel1: { fontSize: theme.fontSizes.md, }, - line: { - borderLeft: - theme.colorScheme === 'light' - ? `1px solid ${theme.colors.gray[1]}` - : `1px solid ${theme.colors.gray[8]}`, - marginLeft: 30, - }, rightIcon: { color: theme.colorScheme === 'light' @@ -89,10 +92,10 @@ export function CollapseButtonControlled< fullWidth = true, id, isOpenOnSelect = false, + indentation, label, leftIcon, level = 0, - line, onCollapseChange, onSelect, opened = false, @@ -129,6 +132,14 @@ export function CollapseButtonControlled< rootClasses.push(classes.rootDeepLevel); labelClasses.push(classes.labelDeepLevel); } + + const indentationStyle = + indentation === 'simple' + ? classes.indentationSimple + : indentation === 'line' + ? classes.indentationLine + : ''; + return ( <> - -
- {activeFilters.map((filter) => ( - filter.onRemove?.(filter)} - pr={3} - rightSection={} - size="xl" - variant="outline" - > - {filter.label} - - ))} -
-
- -
-
- -
- - ); -} diff --git a/packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.mock.tsx b/packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.mock.tsx deleted file mode 100644 index f74543e9..00000000 --- a/packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.mock.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import type { IFiltersItem } from './SidebarFilterMenu'; - -import { Checkbox, Group } from '@mantine/core'; - -export const menu: IFiltersItem[] = [ - { - content: ( - <> - - Dupont - -
- - Martin - -
- - Andrée - - - ), - id: 1, - label: 'Nom du client', - }, - { - children: [ - { - content: ( - <> - - CDI - -
- - CDD - - - ), - id: 10, - label: 'Contrat classique', - }, - { - content: ( - - Freelance - - ), - id: 11, - label: 'Contrat special', - }, - ], - id: 3, - label: 'Type de contrat', - }, - { - id: 8, - label: 'Période', - }, - { id: 9, label: 'Durée du contrat' }, -]; diff --git a/packages/react-front-kit/src/Components/Filters/__snapshots__/Filters.test.tsx.snap b/packages/react-front-kit/src/Components/Filters/__snapshots__/Filters.test.tsx.snap deleted file mode 100644 index 815e8bd2..00000000 --- a/packages/react-front-kit/src/Components/Filters/__snapshots__/Filters.test.tsx.snap +++ /dev/null @@ -1,83 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Filters matches snapshot 1`] = ` -
-
-
-
- - Active filters - - -
-
-
-
-
-
-
- -
-
-
-`; diff --git a/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.stories.tsx b/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.stories.tsx new file mode 100644 index 00000000..2680699f --- /dev/null +++ b/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.stories.tsx @@ -0,0 +1,38 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { FiltersBar as Cmp } from './FiltersBar'; +import { activeFilters } from './FitlersBar.mock'; +import { getMenu } from './SidebarFilterMenu/SidebarFilterMenu.mock'; + +const meta = { + component: Cmp, + tags: ['autodocs'], + title: '3-custom/Components/FiltersBar', +} satisfies Meta; + +export default meta; +type IStory = StoryObj; + +export const WithActiveFilters: IStory = { + args: { + activeFilters, + defaultOpenedActiveFilters: true, + defaultOpenedMenuIds: [1, 3, 10, 11], + deleteButtonLabel: 'Remove all', + filterButtonLabel: 'Filtrer', + menus: getMenu(true), + title: 'Active filters', + }, +}; + +export const WithoutActiveFilters: IStory = { + args: { + activeFilters: [], + defaultOpenedActiveFilters: false, + defaultOpenedMenuIds: [1, 3, 10, 11], + deleteButtonLabel: 'Remove all', + filterButtonLabel: 'Filtrer', + menus: getMenu(false), + title: 'Active filters', + }, +}; diff --git a/packages/react-front-kit/src/Components/Filters/Filters.style.tsx b/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.style.tsx similarity index 55% rename from packages/react-front-kit/src/Components/Filters/Filters.style.tsx rename to packages/react-front-kit/src/Components/FiltersBar/FiltersBar.style.tsx index 9ec61d25..5ad7787e 100644 --- a/packages/react-front-kit/src/Components/Filters/Filters.style.tsx +++ b/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.style.tsx @@ -2,17 +2,33 @@ import { createStyles } from '@mantine/styles'; export const useStyles = createStyles((theme) => ({ activeFilters: { - display: 'flex', - flexWrap: 'nowrap', + flexWrap: 'wrap', marginTop: '16px', }, activeFiltersButtonRoot: { minWidth: '100%', + paddingRight: '0', + }, + activeFiltersCollapseInner: { + display: 'flex', + justifyContent: 'space-between', + }, + activeFiltersCollapseLabel: { + color: theme.colors.gray[0], + textAlign: 'left', + }, + activeFiltersCollapseRoot: { + background: 'inherit', + padding: '0px', }, badgeInner: { + '&::first-letter': { + textTransform: 'uppercase', + }, fontWeight: 600, position: 'relative', right: '4px', + textTransform: 'initial', }, badgeRight: { position: 'relative', @@ -27,15 +43,33 @@ export const useStyles = createStyles((theme) => ({ fontWeight: 'normal', marginBottom: '8px', marginRight: '8px', - textTransform: 'capitalize', + minWidth: '60px', }, bottom: { padding: '24px 24px 48px 24px', }, buttonRemoveRoot: { color: 'white', fontSize: '14px', padding: '0' }, + controlledMenu: { + borderBottom: `${theme.colors.gray[3]} 1px solid`, + color: theme.colors.dark[3], + fontWeight: 600, + paddingBottom: '10px', + }, + controlledMenuButton: { + cursor: 'pointer', + }, + controlledMenuLine: { + background: theme.colors.gray[2], + height: '25px', + width: '1px', + }, middle: { margin: '0px 24px', }, + removeAllFiltersButtonRoot: { + marginTop: '8px', + width: '100%', + }, root: { backgroundColor: 'white', borderRadius: '16px', @@ -49,6 +83,6 @@ export const useStyles = createStyles((theme) => ({ borderRadius: '16px 16px 0px 0px', color: 'white', marginBottom: '24px', - padding: '24px', + padding: '24px 44px', }, })); diff --git a/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.test.tsx b/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.test.tsx new file mode 100644 index 00000000..d1ba10b2 --- /dev/null +++ b/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.test.tsx @@ -0,0 +1,21 @@ +import { renderWithProviders } from '@smile/react-front-kit-shared/test-utils'; + +import { FiltersBar } from './FiltersBar'; +import { activeFilters } from './FitlersBar.mock'; +import { menuWithoutContent } from './SidebarFilterMenu/SidebarFilterMenu.mock'; + +describe('FiltersBar', () => { + it('matches snapshot', () => { + const { container } = renderWithProviders( + , + ); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.tsx b/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.tsx new file mode 100644 index 00000000..9c3b1d12 --- /dev/null +++ b/packages/react-front-kit/src/Components/FiltersBar/FiltersBar.tsx @@ -0,0 +1,219 @@ +'use client'; + +import type { IFiltersItem } from './SidebarFilterMenu/SidebarFilterMenu'; +import type { ReactElement, ReactNode } from 'react'; + +import { ActionIcon, Badge, Box, Button, Group } from '@mantine/core'; +import { CaretDown, CaretUp, TrashSimple, X } from '@phosphor-icons/react'; +import { useMemo, useState } from 'react'; + +import { addPathAndDepth, flattenNestedObjects } from '../../helpers'; +import { CollapseButtonControlled } from '../CollapseButton/CollapseButtonControlled'; + +import { useStyles } from './FiltersBar.style'; +import { SidebarFilterMenu } from './SidebarFilterMenu/SidebarFilterMenu'; + +export interface ISidebarFilter { + categoryId: IId[]; + id: IId; + label: string; + onRemove?: (filter: ISidebarFilter) => void; + value: unknown; +} + +type IId = number | string; + +export interface IFiltersProps { + activeFilters?: ISidebarFilter[] | []; + closeAllFiltersLabel?: string; + defaultOpenedActiveFilters?: boolean; + defaultOpenedMenuIds?: IId[]; + deleteButtonLabel?: string; + filterButtonLabel?: string; + menus?: IFiltersItem[] | undefined; + onDeleteButtonClick?: (filters: ISidebarFilter[]) => void; + onFilterButtonClick?: (filters: ISidebarFilter[]) => void; + openAllFiltersLabel?: string; + title?: ReactNode; +} + +export function FiltersBar(props: IFiltersProps): ReactElement { + const { + activeFilters = [], + closeAllFiltersLabel = 'Close all', + title = 'Active filters', + menus = [], + onDeleteButtonClick, + onFilterButtonClick, + openAllFiltersLabel = 'Open all', + deleteButtonLabel = 'Remove all', + filterButtonLabel = 'Filter', + defaultOpenedMenuIds = [], + defaultOpenedActiveFilters = true, + } = props; + const { classes } = useStyles(); + + const flatFilters = useMemo( + () => flattenNestedObjects(addPathAndDepth(menus)), + [menus], + ); + + const [activeFiltersCollapseOpened, setActiveFiltersCollapseOpened] = + useState(defaultOpenedActiveFilters); + const [openedIds, setOpenedIds] = useState(defaultOpenedMenuIds); + + function addActiveNumberToLabel( + menus?: IFiltersItem[], + ): IFiltersItem[] | undefined { + return menus?.map((menu) => ({ + ...menu, + children: addActiveNumberToLabel(menu.children), + label: `${menu.label}${ + activeFilters + .map((activeFilter) => activeFilter.categoryId) + .flat() + .includes(menu.id) + ? ` (${ + activeFilters.filter((activeFilter) => + activeFilter.categoryId.includes(menu.id), + ).length + })` + : '' + }`, + })); + } + + const filtersWithActiveLabel = addActiveNumberToLabel(menus); + + function handleOpenAllButton(): void { + setOpenedIds(flattenNestedObjects(menus).map((menu) => menu.id)); + } + + function handleCloseAllButton(): void { + setOpenedIds([]); + } + + function handlerOnMenuOpen(id: IId): void { + const menuIds = openedIds; + if (menuIds.includes(id)) { + menuIds.splice(menuIds.indexOf(id), 1); + } else { + menuIds.push(id); + } + setOpenedIds([...menuIds]); + } + + const currentIdisNotInOpenIds = !flatFilters.every((filter) => + openedIds.includes(filter.id), + ); + + return ( + +
+ + {title} ({activeFilters.length}) + + } + onSelect={() => { + setActiveFiltersCollapseOpened(!activeFiltersCollapseOpened); + }} + opened={activeFiltersCollapseOpened} + rightIcon={ + { + setActiveFiltersCollapseOpened(!activeFiltersCollapseOpened); + }} + radius="sm" + variant="transparent" + > + {activeFiltersCollapseOpened ? ( + + ) : ( + + )} + + } + > +
+ {activeFilters.map((filter) => ( + filter.onRemove?.(filter)} + pr={3} + rightSection={} + size="xl" + variant="outline" + > + {filter.label} + + ))} +
+
+
+
+ + {openedIds.length > 0 && ( + + )} + {currentIdisNotInOpenIds && openedIds.length > 0 ? ( + + ) : null} + {currentIdisNotInOpenIds ? ( + + ) : null} + + handlerOnMenuOpen(id)} + openedMenuIds={openedIds} + /> +
+
+ + +
+
+ ); +} diff --git a/packages/react-front-kit/src/Components/FiltersBar/FitlersBar.mock.tsx b/packages/react-front-kit/src/Components/FiltersBar/FitlersBar.mock.tsx new file mode 100644 index 00000000..7e1cec0d --- /dev/null +++ b/packages/react-front-kit/src/Components/FiltersBar/FitlersBar.mock.tsx @@ -0,0 +1,26 @@ +export const activeFilters = [ + { + categoryId: [1], + id: 1, + label: 'Dupont', + value: 'DUPONT', + }, + { + categoryId: [1], + id: 2, + label: 'Martin', + value: 'MARTIN', + }, + { + categoryId: [3, 10], + id: 3, + label: 'Freelance', + value: 'Freelance', + }, + { + categoryId: [3, 11], + id: 4, + label: 'CDI', + value: 'CDI', + }, +]; diff --git a/packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.mock.tsx b/packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.mock.tsx new file mode 100644 index 00000000..1d5a2164 --- /dev/null +++ b/packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.mock.tsx @@ -0,0 +1,89 @@ +import type { IFiltersItem } from './SidebarFilterMenu'; + +import { Checkbox, Group } from '@mantine/core'; + +export function getMenu(checked: boolean): IFiltersItem[] { + return [ + { + content: ( + <> + + Dupont + +
+ + Martin + +
+ + Andrée + + + ), + id: 1, + label: 'Nom du client', + }, + { + children: [ + { + content: ( + <> + + CDI + +
+ + CDD + + + ), + id: 10, + label: 'Contrat classique', + }, + { + content: ( + + Freelance + + ), + id: 11, + label: 'Contrat special', + }, + ], + id: 3, + label: 'Type de contrat', + }, + { + id: 8, + label: 'Période', + }, + { id: 9, label: 'Durée du contrat' }, + ]; +} + +// Because, the random mantine ids to make fail test +export const menuWithoutContent = [ + { + id: 1, + label: 'Nom du client', + }, + { + children: [ + { + id: 10, + label: 'Contrat classique', + }, + { + id: 11, + label: 'Contrat special', + }, + ], + id: 3, + label: 'Type de contrat', + }, + { + id: 8, + label: 'Période', + }, + { id: 9, label: 'Durée du contrat' }, +]; diff --git a/packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.style.tsx b/packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.style.tsx similarity index 100% rename from packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.style.tsx rename to packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.style.tsx diff --git a/packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.test.tsx b/packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.test.tsx similarity index 100% rename from packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.test.tsx rename to packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.test.tsx diff --git a/packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.tsx b/packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.tsx similarity index 84% rename from packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.tsx rename to packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.tsx index fad69dc4..d39bea16 100644 --- a/packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/SidebarFilterMenu.tsx +++ b/packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/SidebarFilterMenu.tsx @@ -55,6 +55,7 @@ export function getRecursiveMenu< } return menu.map((item) => { const { content, children, id, label, leftIcon } = item; + const theme = useMantineTheme(); const collapseStyle = openedMenuIds.includes(id) && selectedId === id @@ -76,6 +77,7 @@ export function getRecursiveMenu< root: classes.buttonRoot, }} id={id} + indentation="simple" isOpenOnSelect label={label} leftIcon={leftIcon} @@ -114,12 +116,10 @@ export function SidebarFilterMenu< const { collapseButtonProps, defaultSelectedId, - hasOnlyOneOpenMenu = false, menu, onMenuOpen, - openedMenuIds, + openedMenuIds = [], } = props; - const { classes } = useStyles(); const flatMenu = useMemo( () => flattenNestedObjects(addPathAndDepth(menu)), @@ -130,43 +130,18 @@ export function SidebarFilterMenu< defaultSelectedId, ); - const [openedIds, setOpenedIds] = useState(() => { - if (defaultSelectedId && !openedMenuIds) { - const path = flatMenu.find((menu) => menu.id === defaultSelectedId) - ?.path as T[] | undefined; - if (path) { - return path; - } - } - return openedMenuIds ?? []; - }); - function handleOpenChange(menuId: T, isOpened: boolean): void { const openedMenuPath = (flatMenu.find((menu) => menu.id === menuId)?.path ?? []) as T[]; onMenuOpen?.(menuId, isOpened, openedMenuPath); - if (hasOnlyOneOpenMenu && isOpened) { - setOpenedIds(openedMenuPath); - } else { - /** Add or remove id being clicked **/ - const exists = openedIds.includes(menuId); - let newOpenedIds; - if (exists) { - newOpenedIds = openedIds.filter((id) => id !== menuId); - } else { - newOpenedIds = openedIds.concat(menuId); - } - setOpenedIds(newOpenedIds); - } } - return (
{getRecursiveMenu( classes, setSelectedId, handleOpenChange, - openedIds, + openedMenuIds, selectedId, menu, collapseButtonProps, diff --git a/packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/__snapshots__/SidebarFilterMenu.test.tsx.snap b/packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/__snapshots__/SidebarFilterMenu.test.tsx.snap similarity index 100% rename from packages/react-front-kit/src/Components/Filters/SidebarFilterMenu/__snapshots__/SidebarFilterMenu.test.tsx.snap rename to packages/react-front-kit/src/Components/FiltersBar/SidebarFilterMenu/__snapshots__/SidebarFilterMenu.test.tsx.snap diff --git a/packages/react-front-kit/src/Components/FiltersBar/__snapshots__/FiltersBar.test.tsx.snap b/packages/react-front-kit/src/Components/FiltersBar/__snapshots__/FiltersBar.test.tsx.snap new file mode 100644 index 00000000..691b8363 --- /dev/null +++ b/packages/react-front-kit/src/Components/FiltersBar/__snapshots__/FiltersBar.test.tsx.snap @@ -0,0 +1,587 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`FiltersBar matches snapshot 1`] = ` +
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + Dupont + + + + + + +
+
+ + Martin + + + + + + +
+
+ + Freelance + + + + + + +
+
+ + CDI + + + + + + +
+
+
+
+
+
+
+ + + +
+
+
+
+ + + + + + +
+
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+
+ + + + + + +
+
+
+
+
+
+
+ + +
+ + +
+
+
+`; diff --git a/packages/react-front-kit/src/Components/SidebarMenu/SidebarMenu.tsx b/packages/react-front-kit/src/Components/SidebarMenu/SidebarMenu.tsx index 33373c67..6ecf6a3e 100644 --- a/packages/react-front-kit/src/Components/SidebarMenu/SidebarMenu.tsx +++ b/packages/react-front-kit/src/Components/SidebarMenu/SidebarMenu.tsx @@ -62,11 +62,11 @@ export function getRecursiveMenu< onMenuOpen(id, isOpened)} onSelect={setSelectedId} opened={openedMenuIds.includes(id)} diff --git a/packages/react-front-kit/src/Components/SidebarMenu/__snapshots__/SidebarMenu.test.tsx.snap b/packages/react-front-kit/src/Components/SidebarMenu/__snapshots__/SidebarMenu.test.tsx.snap index 6f73453b..4ca97a38 100644 --- a/packages/react-front-kit/src/Components/SidebarMenu/__snapshots__/SidebarMenu.test.tsx.snap +++ b/packages/react-front-kit/src/Components/SidebarMenu/__snapshots__/SidebarMenu.test.tsx.snap @@ -347,7 +347,7 @@ exports[`Header matches snapshot 1`] = `