@abyss-project/commons-front-core 9.1.1 → 9.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -0
- package/catalog/catalog-entries.ts +12 -0
- package/catalog/pages/AmbientBackground.tsx +83 -0
- package/catalog/pages/AvatarGroup.tsx +45 -0
- package/catalog/pages/BarChart.tsx +127 -0
- package/catalog/pages/CompanySearchField.tsx +113 -0
- package/catalog/pages/ConfirmDialog.tsx +43 -1
- package/catalog/pages/ConfirmDialogWarning.tsx +45 -0
- package/catalog/pages/CopyField.tsx +24 -1
- package/catalog/pages/EntityImageField.tsx +124 -0
- package/catalog/pages/LineChart.tsx +138 -0
- package/catalog/pages/Pagination.tsx +52 -0
- package/catalog/pages/Section.tsx +16 -2
- package/catalog/pages/TeamAvatar.tsx +40 -0
- package/catalog/pages/UserPicker.tsx +124 -0
- package/catalog/pages/index.ts +20 -0
- package/dist/{AbyssCookieConsentProvider-B7-F6osY.js → AbyssCookieConsentProvider-CeDdkoPq.js} +104 -36
- package/dist/{CookieConsentSettings.component-DxQL4ULz.js → CookieConsentSettings.component-tJE0g-SS.js} +1 -1
- package/dist/components/data/BarChart/BarChart.d.ts +47 -0
- package/dist/components/data/BarChart/BarChart.spec.d.ts +1 -0
- package/dist/components/data/DataTable/DataTableDesktop.d.ts +1 -1
- package/dist/components/data/DataTable/DataTableMobile.d.ts +1 -1
- package/dist/components/data/DataTable/data-table.types.d.ts +6 -0
- package/dist/components/data/LineChart/LineChart.d.ts +44 -0
- package/dist/components/data/LineChart/LineChart.spec.d.ts +1 -0
- package/dist/components/data/LineChart/line-chart-ticks.d.ts +31 -0
- package/dist/components/data/LineChart/line-chart-ticks.spec.d.ts +1 -0
- package/dist/components/data/Pagination/Pagination.d.ts +16 -0
- package/dist/components/data/Pagination/Pagination.spec.d.ts +1 -0
- package/dist/components/data/chart-series-tone.d.ts +21 -0
- package/dist/components/data/chart-series-tone.spec.d.ts +1 -0
- package/dist/components/data/index.d.ts +4 -0
- package/dist/components/inputs/ColorField/ColorField.d.ts +8 -5
- package/dist/components/inputs/CompanySearchField/CompanySearchField.d.ts +24 -0
- package/dist/components/inputs/CompanySearchField/CompanySearchField.spec.d.ts +1 -0
- package/dist/components/inputs/CompanySearchField/pappers-company.d.ts +18 -0
- package/dist/components/inputs/CopyField/CopyField.d.ts +22 -6
- package/dist/components/inputs/EntityImageField/EntityImageField.d.ts +47 -0
- package/dist/components/inputs/EntityImageField/EntityImageField.spec.d.ts +1 -0
- package/dist/components/inputs/UserPicker/UserPicker.d.ts +50 -0
- package/dist/components/inputs/UserPicker/UserPicker.spec.d.ts +1 -0
- package/dist/components/inputs/index.d.ts +3 -0
- package/dist/components/layers/ConfirmDialog/ConfirmDialog.d.ts +6 -2
- package/dist/components/layers/ConfirmDialog/useConfirmDialog.d.ts +21 -0
- package/dist/components/layers/ConfirmDialog/useConfirmDialog.spec.d.ts +1 -0
- package/dist/components/layers/index.d.ts +1 -0
- package/dist/components/meaning/AvatarGroup/AvatarGroup.d.ts +22 -0
- package/dist/components/meaning/AvatarGroup/AvatarGroup.spec.d.ts +1 -0
- package/dist/components/meaning/TeamAvatar/TeamAvatar.d.ts +14 -0
- package/dist/components/meaning/TeamAvatar/TeamAvatar.spec.d.ts +1 -0
- package/dist/components/meaning/index.d.ts +2 -0
- package/dist/components/structure/AmbientBackground/AmbientBackground.d.ts +24 -0
- package/dist/components/structure/AmbientBackground/AmbientBackground.spec.d.ts +1 -0
- package/dist/components/structure/Section/Section.d.ts +10 -2
- package/dist/components/structure/index.d.ts +1 -0
- package/dist/cookie-consent.js +2 -2
- package/dist/design-theme-D3DQFMu-.js +27614 -0
- package/dist/hooks/use-rich-intl.hook.d.ts +68 -0
- package/dist/{index-uLh81uFU.js → index-3wZ_n-X5.js} +2 -2
- package/dist/{index-BuQlif6i.js → index-7E3aXufv.js} +2 -2
- package/dist/{index-iQhqBjKY.js → index-9E4QhCRp.js} +2 -2
- package/dist/{index-BtzB7aR_.js → index-B7yu6Zm9.js} +2 -2
- package/dist/{index-DkcMwm_T.js → index-BK4lWFRR.js} +3 -3
- package/dist/{index-2zbZ2URx.js → index-BTfe4Sz-.js} +3 -3
- package/dist/{index-CspGahq0.js → index-BbwAoYtC.js} +4 -4
- package/dist/{index-Waz6-pQr.js → index-BcUA-oDy.js} +4 -4
- package/dist/{index-CTP0QoCT.js → index-BfICcXrk.js} +3 -3
- package/dist/{index-DflXNluH.js → index-By24n0PI.js} +2 -2
- package/dist/{index-C5OyIHCq.js → index-CMyNL_Kk.js} +2 -2
- package/dist/{index-BloHDADq.js → index-CNMUrFys.js} +35281 -47311
- package/dist/{index-BMM6rvML.js → index-CTkBexi5.js} +2 -2
- package/dist/{index-Bhhwuj39.js → index-CUoOFhRH.js} +2 -2
- package/dist/{index-RkXYGPSf.js → index-CZvosKer.js} +4 -4
- package/dist/{index-uGXjK3xv.js → index-CzkoqdQK.js} +3 -3
- package/dist/{index-CsyAu658.js → index-D3QW807K.js} +2 -2
- package/dist/{index-IooWxH41.js → index-D6Gkj-V6.js} +2 -2
- package/dist/{index-Dew1ymFy.js → index-DYUdQPwj.js} +2 -2
- package/dist/{index-jhW25X__.js → index-DeoE1f9Z.js} +2 -2
- package/dist/{index-BXtPl6pH.js → index-F67JSDx7.js} +1 -1
- package/dist/{index-BAcf97X_.js → index-rpW-_Gh4.js} +2 -2
- package/dist/index.js +5979 -4545
- package/dist/legacy/components/CompanySearchAutocomplete/CompanySearchAutocomplete.d.ts +2 -14
- package/dist/legacy/components/Layouts/AbyssFamilyBanner/AbyssFamilyBanner.component.d.ts +3 -7
- package/dist/legacy/utils/file.utils.d.ts +1 -2
- package/dist/legacy.js +107 -107
- package/dist/theme/tokens/choice-swatches.d.ts +12 -0
- package/dist/theme/tokens/choice-swatches.spec.d.ts +1 -0
- package/dist/theme/tokens/index.d.ts +1 -0
- package/dist/theme/tokens/semantic.d.ts +4 -1
- package/dist/translations/en.d.ts +34 -0
- package/dist/translations/fr.d.ts +34 -0
- package/dist/utils/family.d.ts +12 -0
- package/dist/utils/file.utils.d.ts +10 -0
- package/dist/utils/file.utils.spec.d.ts +1 -0
- package/dist/utils/index.d.ts +2 -0
- package/package.json +1 -1
- package/dist/design-theme-BztWe75w.js +0 -15490
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { styled } from '@mui/material/styles';
|
|
2
|
+
import {
|
|
3
|
+
EntityImageField,
|
|
4
|
+
EntityImageShape,
|
|
5
|
+
EntityImageVariant,
|
|
6
|
+
} from '../../src/components/inputs/EntityImageField/EntityImageField';
|
|
7
|
+
import {
|
|
8
|
+
OrganizationAvatar,
|
|
9
|
+
UserAvatar,
|
|
10
|
+
} from '../../src/components/meaning/Avatar/Avatar';
|
|
11
|
+
import { LogoAbyssSmall } from '../../src/assets';
|
|
12
|
+
import { px } from '../../src/theme/components/shared';
|
|
13
|
+
import { Example, LastEvent, Row, Showcase, useEventLog } from '../frame';
|
|
14
|
+
import { CATALOG_CLOUD_PICKER } from '../cloud-picker-fixture';
|
|
15
|
+
|
|
16
|
+
const AVATAR_SIZE = 72;
|
|
17
|
+
|
|
18
|
+
const picture = () => LogoAbyssSmall;
|
|
19
|
+
|
|
20
|
+
/** A stand-in banner image: the brand gradient over the width. */
|
|
21
|
+
const BannerPicture = styled('div')(({ theme }) => {
|
|
22
|
+
const { tokens, space } = theme.design;
|
|
23
|
+
return {
|
|
24
|
+
height: px(space[10] * 2),
|
|
25
|
+
backgroundImage: `linear-gradient(120deg, ${tokens['brand.gradientFrom']}, ${tokens['brand.gradientTo']})`,
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export const EntityImageFieldPage = () => {
|
|
30
|
+
const { log } = useEventLog();
|
|
31
|
+
return (
|
|
32
|
+
<Showcase
|
|
33
|
+
family="Saisie"
|
|
34
|
+
name="EntityImageField"
|
|
35
|
+
description="L'image d'une entité, changée sur place : l'avatar est lui-même le bouton (pastille d'appareil photo), la bannière porte un bouton en surimpression. Sans AbyssCloud, le bouton ouvre le sélecteur de fichiers ; avec, le menu des sources."
|
|
36
|
+
>
|
|
37
|
+
<Example title="Avatars : photo ronde avec AbyssCloud, logo carré sans">
|
|
38
|
+
<Row>
|
|
39
|
+
<EntityImageField
|
|
40
|
+
variant={EntityImageVariant.Avatar}
|
|
41
|
+
picture={
|
|
42
|
+
<UserAvatar
|
|
43
|
+
userId="u1"
|
|
44
|
+
alias="Mehdi"
|
|
45
|
+
hasThumbnail
|
|
46
|
+
size={AVATAR_SIZE}
|
|
47
|
+
getProfilePictureUrl={picture}
|
|
48
|
+
/>
|
|
49
|
+
}
|
|
50
|
+
label="Changer la photo"
|
|
51
|
+
accept={['image/*']}
|
|
52
|
+
onFile={(file) => log(`fichier ${file.name}`)}
|
|
53
|
+
uploading={false}
|
|
54
|
+
cloudImport={{
|
|
55
|
+
...CATALOG_CLOUD_PICKER,
|
|
56
|
+
onImport: (_space, files) =>
|
|
57
|
+
log(`importé ${files.map((file) => file.name).join(', ')}`),
|
|
58
|
+
}}
|
|
59
|
+
/>
|
|
60
|
+
<EntityImageField
|
|
61
|
+
variant={EntityImageVariant.Avatar}
|
|
62
|
+
shape={EntityImageShape.Square}
|
|
63
|
+
picture={
|
|
64
|
+
<OrganizationAvatar
|
|
65
|
+
orgId="o1"
|
|
66
|
+
name="Abyss"
|
|
67
|
+
hasThumbnail={false}
|
|
68
|
+
size={AVATAR_SIZE}
|
|
69
|
+
getLogoUrl={picture}
|
|
70
|
+
/>
|
|
71
|
+
}
|
|
72
|
+
label="Changer le logo"
|
|
73
|
+
accept={['image/*']}
|
|
74
|
+
onFile={(file) => log(`fichier ${file.name}`)}
|
|
75
|
+
uploading={false}
|
|
76
|
+
/>
|
|
77
|
+
</Row>
|
|
78
|
+
</Example>
|
|
79
|
+
<Example title="Envoi en cours">
|
|
80
|
+
<EntityImageField
|
|
81
|
+
variant={EntityImageVariant.Avatar}
|
|
82
|
+
shape={EntityImageShape.Square}
|
|
83
|
+
picture={
|
|
84
|
+
<OrganizationAvatar
|
|
85
|
+
orgId="o2"
|
|
86
|
+
name="Atlas"
|
|
87
|
+
hasThumbnail={false}
|
|
88
|
+
size={AVATAR_SIZE}
|
|
89
|
+
getLogoUrl={picture}
|
|
90
|
+
/>
|
|
91
|
+
}
|
|
92
|
+
label="Changer le logo"
|
|
93
|
+
onFile={(file) => log(`fichier ${file.name}`)}
|
|
94
|
+
uploading
|
|
95
|
+
/>
|
|
96
|
+
</Example>
|
|
97
|
+
<Example title="Bannière d'organisation" maxWidth={720}>
|
|
98
|
+
<EntityImageField
|
|
99
|
+
variant={EntityImageVariant.Banner}
|
|
100
|
+
picture={<BannerPicture />}
|
|
101
|
+
label="Changer la bannière"
|
|
102
|
+
accept={['image/*']}
|
|
103
|
+
onFile={(file) => log(`bannière ${file.name}`)}
|
|
104
|
+
uploading={false}
|
|
105
|
+
cloudImport={{
|
|
106
|
+
...CATALOG_CLOUD_PICKER,
|
|
107
|
+
onImport: (_space, files) =>
|
|
108
|
+
log(`bannière ${files.map((file) => file.name).join(', ')}`),
|
|
109
|
+
}}
|
|
110
|
+
/>
|
|
111
|
+
</Example>
|
|
112
|
+
<Example title="Bannière, envoi en cours" maxWidth={720}>
|
|
113
|
+
<EntityImageField
|
|
114
|
+
variant={EntityImageVariant.Banner}
|
|
115
|
+
picture={<BannerPicture />}
|
|
116
|
+
label="Changer la bannière"
|
|
117
|
+
onFile={(file) => log(`bannière ${file.name}`)}
|
|
118
|
+
uploading
|
|
119
|
+
/>
|
|
120
|
+
</Example>
|
|
121
|
+
<LastEvent />
|
|
122
|
+
</Showcase>
|
|
123
|
+
);
|
|
124
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { LineChart } from '../../src/components/data/LineChart/LineChart';
|
|
2
|
+
import type {
|
|
3
|
+
LineChartSeries,
|
|
4
|
+
LineChartX,
|
|
5
|
+
} from '../../src/components/data/LineChart/LineChart';
|
|
6
|
+
import { ChartSeriesTone } from '../../src/components/data/chart-series-tone';
|
|
7
|
+
import { Surface } from '../../src/components/structure/Surface/Surface';
|
|
8
|
+
import { Example, Showcase } from '../frame';
|
|
9
|
+
|
|
10
|
+
const START = new Date(2026, 9, 13, 0);
|
|
11
|
+
|
|
12
|
+
const atHour = (hour: number) =>
|
|
13
|
+
new Date(START.getTime() + hour * 60 * 60 * 1000);
|
|
14
|
+
|
|
15
|
+
const REQUESTS = [
|
|
16
|
+
42, 31, 24, 19, 17, 22, 48, 96, 184, 236, 262, 248, 231, 244, 268, 281, 254,
|
|
17
|
+
212, 168, 131, 104, 86, 67, 51,
|
|
18
|
+
];
|
|
19
|
+
const ERRORS = [
|
|
20
|
+
1, 0, 0, 0, 1, 0, 2, 4, 9, 6, 5, 4, 12, 18, 7, 5, 4, 3, 3, 2, 1, 1, 0, 1,
|
|
21
|
+
];
|
|
22
|
+
const LATENCY = [
|
|
23
|
+
88, 84, 81, 80, 79, 83, 94, 118, 141, 152, 158, 155, 149, 162, 171, 166, 150,
|
|
24
|
+
133, 117, 104, 97, 93, 90, 89,
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const hourly = (
|
|
28
|
+
id: string,
|
|
29
|
+
label: string,
|
|
30
|
+
values: number[],
|
|
31
|
+
tone?: ChartSeriesTone,
|
|
32
|
+
): LineChartSeries => ({
|
|
33
|
+
id,
|
|
34
|
+
label,
|
|
35
|
+
points: values.map((y, hour) => ({ x: atHour(hour), y })),
|
|
36
|
+
tone,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
const DELIVERED = REQUESTS.map((value, hour) => value - ERRORS[hour]);
|
|
40
|
+
|
|
41
|
+
const SIX_SERIES: LineChartSeries[] = [
|
|
42
|
+
'Atlas',
|
|
43
|
+
'Board',
|
|
44
|
+
'Draw',
|
|
45
|
+
'Beam',
|
|
46
|
+
'Extract',
|
|
47
|
+
'ShortLink',
|
|
48
|
+
].map((label, index) => ({
|
|
49
|
+
id: label.toLowerCase(),
|
|
50
|
+
label,
|
|
51
|
+
points: Array.from({ length: 12 }, (_, month) => ({
|
|
52
|
+
x: month + 1,
|
|
53
|
+
y: 20 + index * 12 + Math.round(10 * Math.sin((month + index) / 2)),
|
|
54
|
+
})),
|
|
55
|
+
}));
|
|
56
|
+
|
|
57
|
+
const time = new Intl.DateTimeFormat('fr-FR', {
|
|
58
|
+
hour: '2-digit',
|
|
59
|
+
minute: '2-digit',
|
|
60
|
+
});
|
|
61
|
+
const count = new Intl.NumberFormat('fr-FR');
|
|
62
|
+
|
|
63
|
+
const formatHour = (x: LineChartX) =>
|
|
64
|
+
time.format(x instanceof Date ? x : new Date(x));
|
|
65
|
+
const formatMonth = (x: LineChartX) =>
|
|
66
|
+
`M${count.format(x instanceof Date ? x.getMonth() + 1 : x)}`;
|
|
67
|
+
|
|
68
|
+
export const LineChartPage = () => (
|
|
69
|
+
<Showcase
|
|
70
|
+
family="Données"
|
|
71
|
+
name="LineChart"
|
|
72
|
+
description="Courbes Nivo sous abyssNivoTheme : couleurs prises dans l'ordre de la palette data.series, ou dans status.* pour une série à ton ; aires empilées avec stacked ; légende au-delà d'une série, figure nommée et tableau des valeurs pour les lecteurs d'écran."
|
|
73
|
+
>
|
|
74
|
+
<Example title="Une série, aire">
|
|
75
|
+
<Surface padding={4}>
|
|
76
|
+
<LineChart
|
|
77
|
+
series={[hourly('requests', 'Requêtes', REQUESTS)]}
|
|
78
|
+
height={240}
|
|
79
|
+
area
|
|
80
|
+
formatX={formatHour}
|
|
81
|
+
formatY={(y) => count.format(y)}
|
|
82
|
+
label="Requêtes par heure, sur 24 heures"
|
|
83
|
+
/>
|
|
84
|
+
</Surface>
|
|
85
|
+
</Example>
|
|
86
|
+
<Example title="Deux séries">
|
|
87
|
+
<Surface padding={4}>
|
|
88
|
+
<LineChart
|
|
89
|
+
series={[
|
|
90
|
+
hourly('latency', 'Latence p95', LATENCY),
|
|
91
|
+
hourly('errors', 'Erreurs', ERRORS),
|
|
92
|
+
]}
|
|
93
|
+
height={240}
|
|
94
|
+
formatX={formatHour}
|
|
95
|
+
formatY={(y) => count.format(y)}
|
|
96
|
+
label="Latence et erreurs par heure"
|
|
97
|
+
/>
|
|
98
|
+
</Surface>
|
|
99
|
+
</Example>
|
|
100
|
+
<Example title="Empilées, séries à ton (délivrés et échecs)">
|
|
101
|
+
<Surface padding={4}>
|
|
102
|
+
<LineChart
|
|
103
|
+
series={[
|
|
104
|
+
hourly('delivered', 'Délivrés', DELIVERED, ChartSeriesTone.Success),
|
|
105
|
+
hourly('failed', 'Échecs', ERRORS, ChartSeriesTone.Danger),
|
|
106
|
+
]}
|
|
107
|
+
height={240}
|
|
108
|
+
stacked
|
|
109
|
+
formatX={formatHour}
|
|
110
|
+
formatY={(y) => count.format(y)}
|
|
111
|
+
label="Webhooks délivrés et en échec par heure"
|
|
112
|
+
/>
|
|
113
|
+
</Surface>
|
|
114
|
+
</Example>
|
|
115
|
+
<Example title="Palette des six séries">
|
|
116
|
+
<Surface padding={4}>
|
|
117
|
+
<LineChart
|
|
118
|
+
series={SIX_SERIES}
|
|
119
|
+
height={240}
|
|
120
|
+
formatX={formatMonth}
|
|
121
|
+
formatY={(y) => count.format(y)}
|
|
122
|
+
label="Contenus créés par outil et par mois"
|
|
123
|
+
/>
|
|
124
|
+
</Surface>
|
|
125
|
+
</Example>
|
|
126
|
+
<Example title="Aucune donnée">
|
|
127
|
+
<Surface padding={4}>
|
|
128
|
+
<LineChart
|
|
129
|
+
series={[{ id: 'requests', label: 'Requêtes', points: [] }]}
|
|
130
|
+
height={160}
|
|
131
|
+
formatX={formatHour}
|
|
132
|
+
formatY={(y) => count.format(y)}
|
|
133
|
+
label="Requêtes par heure"
|
|
134
|
+
/>
|
|
135
|
+
</Surface>
|
|
136
|
+
</Example>
|
|
137
|
+
</Showcase>
|
|
138
|
+
);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { Pagination } from '../../src/components/data/Pagination/Pagination';
|
|
4
|
+
import { Example, LastEvent, Showcase, useEventLog } from '../frame';
|
|
5
|
+
|
|
6
|
+
/** A paged list the reader can walk through: the page is held here, as a host would. */
|
|
7
|
+
const LivePagination = ({
|
|
8
|
+
initialPage,
|
|
9
|
+
pageCount,
|
|
10
|
+
label,
|
|
11
|
+
}: {
|
|
12
|
+
initialPage: number;
|
|
13
|
+
pageCount: number;
|
|
14
|
+
label: string;
|
|
15
|
+
}) => {
|
|
16
|
+
const { log } = useEventLog();
|
|
17
|
+
const [page, setPage] = useState(initialPage);
|
|
18
|
+
return (
|
|
19
|
+
<Pagination
|
|
20
|
+
page={page}
|
|
21
|
+
pageCount={pageCount}
|
|
22
|
+
label={label}
|
|
23
|
+
onChange={(next) => {
|
|
24
|
+
setPage(next);
|
|
25
|
+
log(`page ${next}`);
|
|
26
|
+
}}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const PaginationPage = () => (
|
|
32
|
+
<Showcase
|
|
33
|
+
family="Données"
|
|
34
|
+
name="Pagination"
|
|
35
|
+
description="Navigation entre les pages d'une liste : précédent, numéros avec ellipses, suivant ; sous 768 px, précédent, « Page x sur y », suivant."
|
|
36
|
+
>
|
|
37
|
+
<Example title="Cinq pages">
|
|
38
|
+
<LivePagination initialPage={2} pageCount={5} label="Pages des membres" />
|
|
39
|
+
</Example>
|
|
40
|
+
<Example title="Quarante pages, au milieu">
|
|
41
|
+
<LivePagination
|
|
42
|
+
initialPage={18}
|
|
43
|
+
pageCount={40}
|
|
44
|
+
label="Pages des permissions"
|
|
45
|
+
/>
|
|
46
|
+
</Example>
|
|
47
|
+
<Example title="Quarante pages, près du début">
|
|
48
|
+
<LivePagination initialPage={3} pageCount={40} label="Pages du journal" />
|
|
49
|
+
</Example>
|
|
50
|
+
<LastEvent />
|
|
51
|
+
</Showcase>
|
|
52
|
+
);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import Button from '@mui/material/Button';
|
|
2
2
|
import ArrowForwardRounded from '@mui/icons-material/ArrowForwardRounded';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
Section,
|
|
5
|
+
SectionTone,
|
|
6
|
+
} from '../../src/components/structure/Section/Section';
|
|
4
7
|
import { KeyValueList } from '../../src/components/data/KeyValueList/KeyValueList';
|
|
5
8
|
import { Columns, Example, LastEvent, Showcase, useEventLog } from '../frame';
|
|
6
9
|
import { ACCOUNTS, LONG_NAV_LABEL, formatEuro } from '../fixtures';
|
|
@@ -12,7 +15,7 @@ export const SectionPage = () => {
|
|
|
12
15
|
<Showcase
|
|
13
16
|
family="Structure"
|
|
14
17
|
name="Section"
|
|
15
|
-
description="Bloc titré d'une page : titre de 16 px, compteur en mono, actions alignées à droite."
|
|
18
|
+
description="Bloc titré d'une page : titre de 16 px, compteur en mono, actions alignées à droite. En ton danger, titre et filet en rouge."
|
|
16
19
|
>
|
|
17
20
|
<Example title="Avec compteur et action">
|
|
18
21
|
<Section
|
|
@@ -67,6 +70,17 @@ export const SectionPage = () => {
|
|
|
67
70
|
/>
|
|
68
71
|
</Section>
|
|
69
72
|
</Example>
|
|
73
|
+
<Example title="Zone de danger">
|
|
74
|
+
<Section title="Zone de danger" tone={SectionTone.Danger}>
|
|
75
|
+
<Button
|
|
76
|
+
variant="outlined"
|
|
77
|
+
color="error"
|
|
78
|
+
onClick={() => log('supprimer l’organisation')}
|
|
79
|
+
>
|
|
80
|
+
Supprimer l’organisation
|
|
81
|
+
</Button>
|
|
82
|
+
</Section>
|
|
83
|
+
</Example>
|
|
70
84
|
<Example title="Titre de 200 caractères sans espace">
|
|
71
85
|
<Section title={LONG_NAV_LABEL} count={12}>
|
|
72
86
|
<LastEvent />
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useTheme } from '@mui/material/styles';
|
|
2
|
+
|
|
3
|
+
import { TeamAvatar } from '../../src/components/meaning/TeamAvatar/TeamAvatar';
|
|
4
|
+
import { Example, Row, Showcase } from '../frame';
|
|
5
|
+
|
|
6
|
+
export const TeamAvatarPage = () => {
|
|
7
|
+
// Stored team colors are user data; the catalog borrows token values so as not to hard-code any.
|
|
8
|
+
const { tokens } = useTheme().design;
|
|
9
|
+
return (
|
|
10
|
+
<Showcase
|
|
11
|
+
family="Sens"
|
|
12
|
+
name="TeamAvatar"
|
|
13
|
+
description="Équipe : l'initiale de son nom sur sa couleur, dans un carré arrondi, à l'encre claire ou sombre qui contraste le mieux. Sans couleur, ou avec une couleur que le navigateur ne sait pas lire, la teinte neutre des avatars."
|
|
14
|
+
>
|
|
15
|
+
<Example title="Couleurs d'équipe, foncées et claires" framed>
|
|
16
|
+
<Row>
|
|
17
|
+
<TeamAvatar name="Design" color={tokens['status.info']} />
|
|
18
|
+
<TeamAvatar name="Ops" color={tokens['status.success']} />
|
|
19
|
+
<TeamAvatar name="Support" color={tokens['status.warning']} />
|
|
20
|
+
<TeamAvatar name="Finance" color={tokens['status.highlight']} />
|
|
21
|
+
<TeamAvatar name="Sécurité" color={tokens['status.danger']} />
|
|
22
|
+
</Row>
|
|
23
|
+
</Example>
|
|
24
|
+
<Example title="Sans couleur, couleur illisible, sans nom" framed>
|
|
25
|
+
<Row>
|
|
26
|
+
<TeamAvatar name="Marketing" color={null} />
|
|
27
|
+
<TeamAvatar name="Ventes" color="pas-une-couleur" />
|
|
28
|
+
<TeamAvatar name="" color={tokens['status.info']} />
|
|
29
|
+
</Row>
|
|
30
|
+
</Example>
|
|
31
|
+
<Example title="Tailles : 22, 32 (défaut), 64" framed>
|
|
32
|
+
<Row>
|
|
33
|
+
<TeamAvatar name="Ops" color={tokens['status.info']} size={22} />
|
|
34
|
+
<TeamAvatar name="Ops" color={tokens['status.info']} />
|
|
35
|
+
<TeamAvatar name="Ops" color={tokens['status.info']} size={64} />
|
|
36
|
+
</Row>
|
|
37
|
+
</Example>
|
|
38
|
+
</Showcase>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { useEffect, useState } from 'react';
|
|
2
|
+
import { UserPicker } from '../../src/components/inputs/UserPicker/UserPicker';
|
|
3
|
+
import type { UserPickerOption } from '../../src/components/inputs/UserPicker/UserPicker';
|
|
4
|
+
import { LogoAbyssSmall } from '../../src/assets';
|
|
5
|
+
import { Example, LastEvent, Showcase, useEventLog } from '../frame';
|
|
6
|
+
|
|
7
|
+
const MEMBERS: UserPickerOption[] = [
|
|
8
|
+
{
|
|
9
|
+
id: 'u1',
|
|
10
|
+
name: 'Mehdi Benali',
|
|
11
|
+
email: 'mehdi@abyss.fr',
|
|
12
|
+
pictureUrl: LogoAbyssSmall,
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
id: 'u2',
|
|
16
|
+
name: 'Alice Martin',
|
|
17
|
+
email: 'alice.martin@karbon-studio.fr',
|
|
18
|
+
pictureUrl: null,
|
|
19
|
+
},
|
|
20
|
+
{ id: 'u3', name: 'Bruno Petit', email: 'bruno@abyss.fr', pictureUrl: null },
|
|
21
|
+
{ id: 'u4', name: 'Clara Durand', email: null, pictureUrl: null },
|
|
22
|
+
{
|
|
23
|
+
id: 'u5',
|
|
24
|
+
name: 'Maximilien-Alexandre de La Tour d’Auvergne',
|
|
25
|
+
email: 'maximilien-alexandre.delatourdauvergne@exemple-tres-long.fr',
|
|
26
|
+
pictureUrl: null,
|
|
27
|
+
},
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
/** Delay of the simulated server search, in ms. */
|
|
31
|
+
const SEARCH_DELAY = 600;
|
|
32
|
+
|
|
33
|
+
/** A server search answered from memory, after a delay: the catalog has no network. */
|
|
34
|
+
const useSimulatedSearch = () => {
|
|
35
|
+
const [query, setQuery] = useState('');
|
|
36
|
+
const [results, setResults] = useState<UserPickerOption[]>(MEMBERS);
|
|
37
|
+
const [loading, setLoading] = useState(false);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
setLoading(true);
|
|
40
|
+
const timer = setTimeout(() => {
|
|
41
|
+
const text = query.trim().toLowerCase();
|
|
42
|
+
setResults(
|
|
43
|
+
MEMBERS.filter((member) =>
|
|
44
|
+
[member.name, member.email ?? ''].some((field) =>
|
|
45
|
+
field.toLowerCase().includes(text),
|
|
46
|
+
),
|
|
47
|
+
),
|
|
48
|
+
);
|
|
49
|
+
setLoading(false);
|
|
50
|
+
}, SEARCH_DELAY);
|
|
51
|
+
return () => clearTimeout(timer);
|
|
52
|
+
}, [query]);
|
|
53
|
+
return { results, loading, search: setQuery };
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const UserPickerPage = () => {
|
|
57
|
+
const { log } = useEventLog();
|
|
58
|
+
const [owner, setOwner] = useState<string | null>('u2');
|
|
59
|
+
const [recipients, setRecipients] = useState<string[]>(['u1', 'u3']);
|
|
60
|
+
const [target, setTarget] = useState<string | null>(null);
|
|
61
|
+
const remote = useSimulatedSearch();
|
|
62
|
+
return (
|
|
63
|
+
<Showcase
|
|
64
|
+
family="Saisie"
|
|
65
|
+
name="UserPicker"
|
|
66
|
+
description="Choix d'un utilisateur ou de plusieurs : avatar, nom et e-mail dans chaque option, recherche sur le nom et l'e-mail (locale, ou confiée au serveur par onSearch). En multiple, les choisis sont des puces que le clavier retire."
|
|
67
|
+
>
|
|
68
|
+
<Example title="Choix simple" maxWidth={480}>
|
|
69
|
+
<UserPicker
|
|
70
|
+
options={MEMBERS}
|
|
71
|
+
value={owner}
|
|
72
|
+
onChange={(next) => {
|
|
73
|
+
setOwner(next);
|
|
74
|
+
log(`responsable ${next ?? 'aucun'}`);
|
|
75
|
+
}}
|
|
76
|
+
label="Responsable de l’équipe"
|
|
77
|
+
placeholder="Choisir un membre"
|
|
78
|
+
noOptionsText="Aucun membre ne correspond"
|
|
79
|
+
/>
|
|
80
|
+
</Example>
|
|
81
|
+
<Example title="Choix multiple" maxWidth={480}>
|
|
82
|
+
<UserPicker
|
|
83
|
+
multiple
|
|
84
|
+
options={MEMBERS}
|
|
85
|
+
value={recipients}
|
|
86
|
+
onChange={(next) => {
|
|
87
|
+
setRecipients(next);
|
|
88
|
+
log(`destinataires ${next.join(', ')}`);
|
|
89
|
+
}}
|
|
90
|
+
label="Destinataires du rapport"
|
|
91
|
+
placeholder="Ajouter un membre"
|
|
92
|
+
noOptionsText="Aucun membre ne correspond"
|
|
93
|
+
/>
|
|
94
|
+
</Example>
|
|
95
|
+
<Example title="Recherche serveur, propriétaire exclu" maxWidth={480}>
|
|
96
|
+
<UserPicker
|
|
97
|
+
options={remote.results}
|
|
98
|
+
onSearch={remote.search}
|
|
99
|
+
loading={remote.loading}
|
|
100
|
+
value={target}
|
|
101
|
+
onChange={(next) => {
|
|
102
|
+
setTarget(next);
|
|
103
|
+
log(`nouveau propriétaire ${next ?? 'aucun'}`);
|
|
104
|
+
}}
|
|
105
|
+
disabledIds={['u1']}
|
|
106
|
+
label="Nouveau propriétaire"
|
|
107
|
+
placeholder="Rechercher un membre"
|
|
108
|
+
noOptionsText="Aucun membre ne correspond"
|
|
109
|
+
/>
|
|
110
|
+
</Example>
|
|
111
|
+
<Example title="Inactif" maxWidth={480}>
|
|
112
|
+
<UserPicker
|
|
113
|
+
options={MEMBERS}
|
|
114
|
+
value="u1"
|
|
115
|
+
onChange={() => undefined}
|
|
116
|
+
label="Responsable de l’équipe"
|
|
117
|
+
noOptionsText="Aucun membre ne correspond"
|
|
118
|
+
disabled
|
|
119
|
+
/>
|
|
120
|
+
</Example>
|
|
121
|
+
<LastEvent />
|
|
122
|
+
</Showcase>
|
|
123
|
+
);
|
|
124
|
+
};
|
package/catalog/pages/index.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import type { ComponentType } from 'react';
|
|
2
2
|
import { AccountMenuPage } from './AccountMenu';
|
|
3
3
|
import { ActionBarPage } from './ActionBar';
|
|
4
|
+
import { AmbientBackgroundPage } from './AmbientBackground';
|
|
4
5
|
import { AppShellPage } from './AppShell';
|
|
5
6
|
import { AvatarPage } from './Avatar';
|
|
7
|
+
import { BarChartPage } from './BarChart';
|
|
6
8
|
import { BottomSheetPage } from './BottomSheet';
|
|
7
9
|
import { CalloutPage } from './Callout';
|
|
8
10
|
import { ChartThemePage } from './ChartTheme';
|
|
@@ -10,8 +12,16 @@ import { CloudImportPage } from './CloudImport';
|
|
|
10
12
|
import { ColorFieldPage } from './ColorField';
|
|
11
13
|
import { CommandPalettePage } from './CommandPalette';
|
|
12
14
|
import { ConfirmDialogPage } from './ConfirmDialog';
|
|
15
|
+
import { ConfirmDialogWarningPage } from './ConfirmDialogWarning';
|
|
13
16
|
import { ContextSelectorPage } from './ContextSelector';
|
|
14
17
|
import { CopyFieldPage } from './CopyField';
|
|
18
|
+
import { LineChartPage } from './LineChart';
|
|
19
|
+
import { PaginationPage } from './Pagination';
|
|
20
|
+
import { AvatarGroupPage } from './AvatarGroup';
|
|
21
|
+
import { TeamAvatarPage } from './TeamAvatar';
|
|
22
|
+
import { UserPickerPage } from './UserPicker';
|
|
23
|
+
import { CompanySearchFieldPage } from './CompanySearchField';
|
|
24
|
+
import { EntityImageFieldPage } from './EntityImageField';
|
|
15
25
|
import { DataTablePage } from './DataTable';
|
|
16
26
|
import { DateFieldPage } from './DateField';
|
|
17
27
|
import { DateRangeFieldPage } from './DateRangeField';
|
|
@@ -58,8 +68,10 @@ import { UsageMeterPage } from './UsageMeter';
|
|
|
58
68
|
export const CATALOG_PAGES: Record<string, ComponentType> = {
|
|
59
69
|
AccountMenu: AccountMenuPage,
|
|
60
70
|
ActionBar: ActionBarPage,
|
|
71
|
+
AmbientBackground: AmbientBackgroundPage,
|
|
61
72
|
AppShell: AppShellPage,
|
|
62
73
|
Avatar: AvatarPage,
|
|
74
|
+
BarChart: BarChartPage,
|
|
63
75
|
BottomSheet: BottomSheetPage,
|
|
64
76
|
Callout: CalloutPage,
|
|
65
77
|
ChartTheme: ChartThemePage,
|
|
@@ -67,8 +79,16 @@ export const CATALOG_PAGES: Record<string, ComponentType> = {
|
|
|
67
79
|
ColorField: ColorFieldPage,
|
|
68
80
|
CommandPalette: CommandPalettePage,
|
|
69
81
|
ConfirmDialog: ConfirmDialogPage,
|
|
82
|
+
ConfirmDialogWarning: ConfirmDialogWarningPage,
|
|
70
83
|
ContextSelector: ContextSelectorPage,
|
|
71
84
|
CopyField: CopyFieldPage,
|
|
85
|
+
LineChart: LineChartPage,
|
|
86
|
+
Pagination: PaginationPage,
|
|
87
|
+
AvatarGroup: AvatarGroupPage,
|
|
88
|
+
TeamAvatar: TeamAvatarPage,
|
|
89
|
+
UserPicker: UserPickerPage,
|
|
90
|
+
CompanySearchField: CompanySearchFieldPage,
|
|
91
|
+
EntityImageField: EntityImageFieldPage,
|
|
72
92
|
DataTable: DataTablePage,
|
|
73
93
|
DateField: DateFieldPage,
|
|
74
94
|
DateRangeField: DateRangeFieldPage,
|