@cratis/scene.blueprint.default 4.36.0 → 4.37.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.
Files changed (105) hide show
  1. package/ComponentName.ts +9 -0
  2. package/defaultBlueprintComponents.ts +4 -1
  3. package/dist/cjs/ComponentName.js +3 -0
  4. package/dist/cjs/ComponentName.js.map +1 -1
  5. package/dist/cjs/defaultBlueprint.js +1 -0
  6. package/dist/cjs/defaultBlueprint.js.map +1 -1
  7. package/dist/cjs/defaultBlueprintComponentMetadata.js +1 -0
  8. package/dist/cjs/defaultBlueprintComponentMetadata.js.map +1 -1
  9. package/dist/cjs/defaultBlueprintComponents.js +7 -1
  10. package/dist/cjs/defaultBlueprintComponents.js.map +1 -1
  11. package/dist/cjs/foundation/ApprovalChainStepper.js +130 -0
  12. package/dist/cjs/foundation/ApprovalChainStepper.js.map +1 -0
  13. package/dist/cjs/foundation/OrgTree.js +188 -0
  14. package/dist/cjs/foundation/OrgTree.js.map +1 -0
  15. package/dist/cjs/foundation/PermissionMatrix.js +136 -0
  16. package/dist/cjs/foundation/PermissionMatrix.js.map +1 -0
  17. package/dist/cjs/foundation/approvalModel.js +87 -0
  18. package/dist/cjs/foundation/approvalModel.js.map +1 -0
  19. package/dist/cjs/foundation/foundationComponentMetadata.js +21 -0
  20. package/dist/cjs/foundation/foundationComponentMetadata.js.map +1 -1
  21. package/dist/cjs/foundation/foundationDescriptors.js +118 -0
  22. package/dist/cjs/foundation/foundationDescriptors.js.map +1 -1
  23. package/dist/cjs/foundation/foundationSamples.js +116 -0
  24. package/dist/cjs/foundation/foundationSamples.js.map +1 -1
  25. package/dist/cjs/foundation/foundationStrings.js +12 -1
  26. package/dist/cjs/foundation/foundationStrings.js.map +1 -1
  27. package/dist/cjs/foundation/orgModel.js +106 -0
  28. package/dist/cjs/foundation/orgModel.js.map +1 -0
  29. package/dist/cjs/foundation/permissionModel.js +84 -0
  30. package/dist/cjs/foundation/permissionModel.js.map +1 -0
  31. package/dist/cjs/index.js +26 -0
  32. package/dist/cjs/index.js.map +1 -1
  33. package/dist/esm/ComponentName.d.ts +4 -1
  34. package/dist/esm/ComponentName.d.ts.map +1 -1
  35. package/dist/esm/ComponentName.js +3 -0
  36. package/dist/esm/ComponentName.js.map +1 -1
  37. package/dist/esm/defaultBlueprint.js +1 -0
  38. package/dist/esm/defaultBlueprint.js.map +1 -1
  39. package/dist/esm/defaultBlueprintComponentMetadata.js +1 -0
  40. package/dist/esm/defaultBlueprintComponentMetadata.js.map +1 -1
  41. package/dist/esm/defaultBlueprintComponents.d.ts.map +1 -1
  42. package/dist/esm/defaultBlueprintComponents.js +7 -1
  43. package/dist/esm/defaultBlueprintComponents.js.map +1 -1
  44. package/dist/esm/foundation/ApprovalChainStepper.d.ts +3 -0
  45. package/dist/esm/foundation/ApprovalChainStepper.d.ts.map +1 -0
  46. package/dist/esm/foundation/ApprovalChainStepper.js +128 -0
  47. package/dist/esm/foundation/ApprovalChainStepper.js.map +1 -0
  48. package/dist/esm/foundation/Foundation.stories.d.ts +8 -0
  49. package/dist/esm/foundation/Foundation.stories.d.ts.map +1 -1
  50. package/dist/esm/foundation/Foundation.stories.js +8 -0
  51. package/dist/esm/foundation/Foundation.stories.js.map +1 -1
  52. package/dist/esm/foundation/OrgTree.d.ts +3 -0
  53. package/dist/esm/foundation/OrgTree.d.ts.map +1 -0
  54. package/dist/esm/foundation/OrgTree.js +186 -0
  55. package/dist/esm/foundation/OrgTree.js.map +1 -0
  56. package/dist/esm/foundation/PermissionMatrix.d.ts +3 -0
  57. package/dist/esm/foundation/PermissionMatrix.d.ts.map +1 -0
  58. package/dist/esm/foundation/PermissionMatrix.js +134 -0
  59. package/dist/esm/foundation/PermissionMatrix.js.map +1 -0
  60. package/dist/esm/foundation/approvalModel.d.ts +27 -0
  61. package/dist/esm/foundation/approvalModel.d.ts.map +1 -0
  62. package/dist/esm/foundation/approvalModel.js +81 -0
  63. package/dist/esm/foundation/approvalModel.js.map +1 -0
  64. package/dist/esm/foundation/foundationComponentMetadata.d.ts.map +1 -1
  65. package/dist/esm/foundation/foundationComponentMetadata.js +21 -0
  66. package/dist/esm/foundation/foundationComponentMetadata.js.map +1 -1
  67. package/dist/esm/foundation/foundationDescriptors.d.ts.map +1 -1
  68. package/dist/esm/foundation/foundationDescriptors.js +118 -0
  69. package/dist/esm/foundation/foundationDescriptors.js.map +1 -1
  70. package/dist/esm/foundation/foundationSamples.d.ts.map +1 -1
  71. package/dist/esm/foundation/foundationSamples.js +116 -0
  72. package/dist/esm/foundation/foundationSamples.js.map +1 -1
  73. package/dist/esm/foundation/foundationStrings.d.ts +11 -0
  74. package/dist/esm/foundation/foundationStrings.d.ts.map +1 -1
  75. package/dist/esm/foundation/foundationStrings.js +12 -1
  76. package/dist/esm/foundation/foundationStrings.js.map +1 -1
  77. package/dist/esm/foundation/index.d.ts +6 -0
  78. package/dist/esm/foundation/index.d.ts.map +1 -1
  79. package/dist/esm/foundation/index.js +6 -0
  80. package/dist/esm/foundation/index.js.map +1 -1
  81. package/dist/esm/foundation/orgModel.d.ts +20 -0
  82. package/dist/esm/foundation/orgModel.d.ts.map +1 -0
  83. package/dist/esm/foundation/orgModel.js +99 -0
  84. package/dist/esm/foundation/orgModel.js.map +1 -0
  85. package/dist/esm/foundation/permissionModel.d.ts +24 -0
  86. package/dist/esm/foundation/permissionModel.d.ts.map +1 -0
  87. package/dist/esm/foundation/permissionModel.js +77 -0
  88. package/dist/esm/foundation/permissionModel.js.map +1 -0
  89. package/dist/esm/index.js +6 -0
  90. package/dist/esm/index.js.map +1 -1
  91. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  92. package/foundation/ApprovalChainStepper.tsx +66 -0
  93. package/foundation/Foundation.stories.tsx +8 -0
  94. package/foundation/OrgTree.tsx +101 -0
  95. package/foundation/PermissionMatrix.tsx +82 -0
  96. package/foundation/approvalModel.ts +88 -0
  97. package/foundation/foundationComponentMetadata.ts +3 -0
  98. package/foundation/foundationDescriptors.ts +74 -0
  99. package/foundation/foundationSamples.ts +30 -0
  100. package/foundation/foundationStrings.ts +11 -0
  101. package/foundation/index.ts +6 -0
  102. package/foundation/orgModel.ts +85 -0
  103. package/foundation/permissionModel.ts +85 -0
  104. package/package.json +8 -8
  105. package/shell/layout.css +184 -0
@@ -0,0 +1,85 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /** A role: a column of the matrix. */
5
+ export interface MatrixRole {
6
+ id: string;
7
+ label: string;
8
+ }
9
+
10
+ /** A permission: a row of the matrix, optionally in a named group. */
11
+ export interface MatrixPermission {
12
+ id: string;
13
+ label: string;
14
+ group?: string;
15
+ }
16
+
17
+ /** One role holding one permission. */
18
+ export interface MatrixGrant {
19
+ role: string;
20
+ permission: string;
21
+ }
22
+
23
+ /** A named run of permissions, for the group heading rows. */
24
+ export interface MatrixSection {
25
+ group?: string;
26
+ permissions: MatrixPermission[];
27
+ }
28
+
29
+ const records = (value: unknown): Record<string, unknown>[] =>
30
+ Array.isArray(value) ? value.filter((entry): entry is Record<string, unknown> => typeof entry === 'object' && entry !== null && !Array.isArray(entry)) : [];
31
+
32
+ /** Reads roles, dropping those without an id and repeated ids. */
33
+ export function readRoles(value: unknown): MatrixRole[] {
34
+ const seen = new Set<string>();
35
+ return records(value).flatMap(entry => {
36
+ if (typeof entry.id !== 'string' || entry.id.length === 0 || seen.has(entry.id)) return [];
37
+ seen.add(entry.id);
38
+ return [{ id: entry.id, label: typeof entry.label === 'string' && entry.label.length > 0 ? entry.label : entry.id }];
39
+ });
40
+ }
41
+
42
+ /** Reads permissions, dropping those without an id and repeated ids. */
43
+ export function readPermissions(value: unknown): MatrixPermission[] {
44
+ const seen = new Set<string>();
45
+ return records(value).flatMap(entry => {
46
+ if (typeof entry.id !== 'string' || entry.id.length === 0 || seen.has(entry.id)) return [];
47
+ seen.add(entry.id);
48
+ return [{ id: entry.id, label: typeof entry.label === 'string' && entry.label.length > 0 ? entry.label : entry.id, ...(typeof entry.group === 'string' && entry.group.length > 0 ? { group: entry.group } : {}) }];
49
+ });
50
+ }
51
+
52
+ /** Reads grants, keeping each pair once and only for a role and a permission that exist: a grant of something that was deleted is not shown as held. */
53
+ export function readGrants(value: unknown, roles: MatrixRole[], permissions: MatrixPermission[]): MatrixGrant[] {
54
+ const roleIds = new Set(roles.map(role => role.id));
55
+ const permissionIds = new Set(permissions.map(permission => permission.id));
56
+ const seen = new Set<string>();
57
+
58
+ return records(value).flatMap(entry => {
59
+ const { role, permission } = entry;
60
+ if (typeof role !== 'string' || typeof permission !== 'string' || !roleIds.has(role) || !permissionIds.has(permission)) return [];
61
+ const key = `${role}\u0000${permission}`;
62
+ if (seen.has(key)) return [];
63
+ seen.add(key);
64
+ return [{ role, permission }];
65
+ });
66
+ }
67
+
68
+ /** Whether a role holds a permission. */
69
+ export const isGranted = (grants: MatrixGrant[], role: string, permission: string): boolean => grants.some(grant => grant.role === role && grant.permission === permission);
70
+
71
+ /** Grants a permission to a role, or takes it away, leaving every other grant as it was. */
72
+ export const setGrant = (grants: MatrixGrant[], role: string, permission: string, granted: boolean): MatrixGrant[] =>
73
+ granted ? (isGranted(grants, role, permission) ? grants : [...grants, { role, permission }]) : grants.filter(grant => !(grant.role === role && grant.permission === permission));
74
+
75
+ /** Groups the permissions into runs by their group, in the order first seen, with the ungrouped ones in a run of their own. */
76
+ export function sectionsOf(permissions: MatrixPermission[]): MatrixSection[] {
77
+ const sections: MatrixSection[] = [];
78
+ for (const permission of permissions) {
79
+ const section = sections.find(candidate => candidate.group === permission.group);
80
+ if (section) section.permissions.push(permission);
81
+ else sections.push({ ...(permission.group === undefined ? {} : { group: permission.group }), permissions: [permission] });
82
+ }
83
+
84
+ return sections;
85
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/scene.blueprint.default",
3
- "version": "4.36.0",
3
+ "version": "4.37.0",
4
4
  "description": "The default blueprint: application shell layouts, the screen and dialog templates that go inside them, the components that fill their slots, and two themes.",
5
5
  "keywords": [
6
6
  "cratis",
@@ -55,15 +55,15 @@
55
55
  "build-storybook": "storybook build"
56
56
  },
57
57
  "dependencies": {
58
- "@cratis/scene.engine": "4.36.0",
59
- "@cratis/scene.model": "4.36.0",
60
- "@cratis/scene.react": "4.36.0"
58
+ "@cratis/scene.engine": "4.37.0",
59
+ "@cratis/scene.model": "4.37.0",
60
+ "@cratis/scene.react": "4.37.0"
61
61
  },
62
62
  "devDependencies": {
63
- "@cratis/scene.engine": "4.36.0",
64
- "@cratis/scene.model": "4.36.0",
65
- "@cratis/scene.primereact": "4.36.0",
66
- "@cratis/scene.react": "4.36.0",
63
+ "@cratis/scene.engine": "4.37.0",
64
+ "@cratis/scene.model": "4.37.0",
65
+ "@cratis/scene.primereact": "4.37.0",
66
+ "@cratis/scene.react": "4.37.0",
67
67
  "@primereact/core": "11.2.0",
68
68
  "@primereact/headless": "11.2.0",
69
69
  "@primeuix/themes": "^3.0.1",
package/shell/layout.css CHANGED
@@ -1841,3 +1841,187 @@
1841
1841
  color: var(--foundation-danger);
1842
1842
  font-weight: 600;
1843
1843
  }
1844
+
1845
+ /* Approval chain. */
1846
+ .foundation-approval-chain {
1847
+ padding: var(--foundation-space-4);
1848
+ border: 1px solid var(--foundation-border);
1849
+ border-radius: var(--foundation-radius);
1850
+ background: var(--foundation-surface);
1851
+ }
1852
+
1853
+ .foundation-approval-outcome {
1854
+ margin-block: 0 var(--foundation-space-3);
1855
+ font-weight: 700;
1856
+ }
1857
+
1858
+ .foundation-approval-steps {
1859
+ display: flex;
1860
+ flex-wrap: wrap;
1861
+ gap: var(--foundation-space-4);
1862
+ margin: 0;
1863
+ padding: 0;
1864
+ list-style: none;
1865
+ }
1866
+
1867
+ .foundation-approval-step {
1868
+ position: relative;
1869
+ display: flex;
1870
+ flex: 1 1 10rem;
1871
+ flex-direction: column;
1872
+ align-items: flex-start;
1873
+ gap: var(--foundation-space-1);
1874
+ min-inline-size: 0;
1875
+ padding-block-start: var(--foundation-space-3);
1876
+ border-block-start: 3px solid var(--foundation-border);
1877
+ }
1878
+
1879
+ .foundation-approval-step[data-state='approved'] { border-block-start-color: var(--foundation-success); }
1880
+ .foundation-approval-step[data-state='current'] { border-block-start-color: var(--foundation-info); }
1881
+ .foundation-approval-step[data-state='rejected'] { border-block-start-color: var(--foundation-danger); }
1882
+
1883
+ .foundation-approval-comment {
1884
+ overflow-wrap: anywhere;
1885
+ font-style: italic;
1886
+ }
1887
+
1888
+ .foundation-approval-steps[data-orientation='vertical'] {
1889
+ flex-direction: column;
1890
+ }
1891
+
1892
+ .foundation-approval-steps[data-orientation='vertical'] .foundation-approval-step {
1893
+ flex-basis: auto;
1894
+ padding-block-start: 0;
1895
+ padding-inline-start: var(--foundation-space-3);
1896
+ border-block-start: 0;
1897
+ border-inline-start: 3px solid var(--foundation-border);
1898
+ }
1899
+
1900
+ .foundation-approval-steps[data-orientation='vertical'] .foundation-approval-step[data-state='approved'] { border-inline-start-color: var(--foundation-success); }
1901
+ .foundation-approval-steps[data-orientation='vertical'] .foundation-approval-step[data-state='current'] { border-inline-start-color: var(--foundation-info); }
1902
+ .foundation-approval-steps[data-orientation='vertical'] .foundation-approval-step[data-state='rejected'] { border-inline-start-color: var(--foundation-danger); }
1903
+
1904
+ @media (max-width: 40rem) {
1905
+ .foundation-approval-steps {
1906
+ flex-direction: column;
1907
+ }
1908
+
1909
+ .foundation-approval-step {
1910
+ flex-basis: auto;
1911
+ padding-block-start: 0;
1912
+ padding-inline-start: var(--foundation-space-3);
1913
+ border-block-start: 0;
1914
+ border-inline-start: 3px solid var(--foundation-border);
1915
+ }
1916
+
1917
+ .foundation-approval-step[data-state='approved'] { border-inline-start-color: var(--foundation-success); }
1918
+ .foundation-approval-step[data-state='current'] { border-inline-start-color: var(--foundation-info); }
1919
+ .foundation-approval-step[data-state='rejected'] { border-inline-start-color: var(--foundation-danger); }
1920
+ }
1921
+
1922
+ /* Org tree. */
1923
+ .foundation-org-tree {
1924
+ padding: var(--foundation-space-2);
1925
+ border: 1px solid var(--foundation-border);
1926
+ border-radius: var(--foundation-radius);
1927
+ background: var(--foundation-surface);
1928
+ }
1929
+
1930
+ .foundation-tree {
1931
+ display: flex;
1932
+ flex-direction: column;
1933
+ margin: 0;
1934
+ padding: 0;
1935
+ list-style: none;
1936
+ }
1937
+
1938
+ .foundation-tree-item {
1939
+ display: flex;
1940
+ align-items: center;
1941
+ gap: var(--foundation-space-2);
1942
+ min-block-size: var(--foundation-row-height);
1943
+ padding-inline-end: var(--foundation-space-2);
1944
+ border-radius: var(--foundation-radius);
1945
+ cursor: pointer;
1946
+ }
1947
+
1948
+ .foundation-tree-item:hover {
1949
+ background: var(--foundation-hover);
1950
+ }
1951
+
1952
+ .foundation-tree-item[data-selected='true'] {
1953
+ background: var(--foundation-highlight);
1954
+ color: var(--foundation-highlight-text);
1955
+ box-shadow: inset 3px 0 0 var(--foundation-primary);
1956
+ }
1957
+
1958
+ .foundation-tree-text {
1959
+ display: flex;
1960
+ flex: 1;
1961
+ flex-direction: column;
1962
+ min-inline-size: 0;
1963
+ }
1964
+
1965
+ .foundation-tree-spacer {
1966
+ flex: none;
1967
+ inline-size: 2.25rem;
1968
+ }
1969
+
1970
+ .foundation-tree-item[data-selected='true'] .foundation-count {
1971
+ color: inherit;
1972
+ }
1973
+
1974
+ /* Permission matrix. */
1975
+ .foundation-permission-matrix {
1976
+ border: 1px solid var(--foundation-border);
1977
+ border-radius: var(--foundation-radius);
1978
+ background: var(--foundation-surface);
1979
+ }
1980
+
1981
+ .foundation-matrix-scroll {
1982
+ overflow-x: auto;
1983
+ }
1984
+
1985
+ .foundation-matrix {
1986
+ inline-size: 100%;
1987
+ border-collapse: collapse;
1988
+ }
1989
+
1990
+ .foundation-matrix th,
1991
+ .foundation-matrix td {
1992
+ min-block-size: var(--foundation-row-height);
1993
+ padding: var(--foundation-space-2) var(--foundation-space-3);
1994
+ border-block-end: 1px solid var(--foundation-border);
1995
+ text-align: center;
1996
+ white-space: nowrap;
1997
+ }
1998
+
1999
+ .foundation-matrix th[scope='row'],
2000
+ .foundation-matrix thead th:first-child {
2001
+ position: sticky;
2002
+ inset-inline-start: 0;
2003
+ background: var(--foundation-surface);
2004
+ text-align: start;
2005
+ }
2006
+
2007
+ .foundation-matrix-group th {
2008
+ background: var(--foundation-background);
2009
+ color: var(--foundation-muted);
2010
+ font-size: 0.875rem;
2011
+ text-align: start;
2012
+ }
2013
+
2014
+ .foundation-matrix input[type='checkbox'] {
2015
+ inline-size: 1.25rem;
2016
+ block-size: 1.25rem;
2017
+ }
2018
+
2019
+ .foundation-matrix td[data-granted='true'] .foundation-matrix-state {
2020
+ color: var(--foundation-success);
2021
+ }
2022
+
2023
+ .foundation-matrix-state {
2024
+ display: inline-flex;
2025
+ align-items: center;
2026
+ justify-content: center;
2027
+ }