@cratis/scene.blueprint.default 4.35.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 (175) hide show
  1. package/ComponentName.ts +21 -0
  2. package/defaultBlueprintComponents.ts +8 -1
  3. package/dist/cjs/ComponentName.js +7 -0
  4. package/dist/cjs/ComponentName.js.map +1 -1
  5. package/dist/cjs/defaultBlueprint.js +2 -0
  6. package/dist/cjs/defaultBlueprint.js.map +1 -1
  7. package/dist/cjs/defaultBlueprintComponentMetadata.js +2 -0
  8. package/dist/cjs/defaultBlueprintComponentMetadata.js.map +1 -1
  9. package/dist/cjs/defaultBlueprintComponents.js +15 -1
  10. package/dist/cjs/defaultBlueprintComponents.js.map +1 -1
  11. package/dist/cjs/foundation/ActivityFeed.js +122 -0
  12. package/dist/cjs/foundation/ActivityFeed.js.map +1 -0
  13. package/dist/cjs/foundation/ApprovalChainStepper.js +130 -0
  14. package/dist/cjs/foundation/ApprovalChainStepper.js.map +1 -0
  15. package/dist/cjs/foundation/AvatarStack.js +73 -0
  16. package/dist/cjs/foundation/AvatarStack.js.map +1 -0
  17. package/dist/cjs/foundation/ChecklistSection.js +174 -0
  18. package/dist/cjs/foundation/ChecklistSection.js.map +1 -0
  19. package/dist/cjs/foundation/FileUploader.js +218 -0
  20. package/dist/cjs/foundation/FileUploader.js.map +1 -0
  21. package/dist/cjs/foundation/FileUploaderHandler.js +17 -0
  22. package/dist/cjs/foundation/FileUploaderHandler.js.map +1 -0
  23. package/dist/cjs/foundation/OrgTree.js +188 -0
  24. package/dist/cjs/foundation/OrgTree.js.map +1 -0
  25. package/dist/cjs/foundation/PermissionMatrix.js +136 -0
  26. package/dist/cjs/foundation/PermissionMatrix.js.map +1 -0
  27. package/dist/cjs/foundation/activityModel.js +63 -0
  28. package/dist/cjs/foundation/activityModel.js.map +1 -0
  29. package/dist/cjs/foundation/approvalModel.js +87 -0
  30. package/dist/cjs/foundation/approvalModel.js.map +1 -0
  31. package/dist/cjs/foundation/avatarModel.js +42 -0
  32. package/dist/cjs/foundation/avatarModel.js.map +1 -0
  33. package/dist/cjs/foundation/checklistModel.js +59 -0
  34. package/dist/cjs/foundation/checklistModel.js.map +1 -0
  35. package/dist/cjs/foundation/formatting.js +11 -0
  36. package/dist/cjs/foundation/formatting.js.map +1 -1
  37. package/dist/cjs/foundation/foundationComponentMetadata.js +47 -0
  38. package/dist/cjs/foundation/foundationComponentMetadata.js.map +1 -1
  39. package/dist/cjs/foundation/foundationDescriptors.js +246 -0
  40. package/dist/cjs/foundation/foundationDescriptors.js.map +1 -1
  41. package/dist/cjs/foundation/foundationSamples.js +230 -0
  42. package/dist/cjs/foundation/foundationSamples.js.map +1 -1
  43. package/dist/cjs/foundation/foundationStrings.js +27 -1
  44. package/dist/cjs/foundation/foundationStrings.js.map +1 -1
  45. package/dist/cjs/foundation/orgModel.js +106 -0
  46. package/dist/cjs/foundation/orgModel.js.map +1 -0
  47. package/dist/cjs/foundation/permissionModel.js +84 -0
  48. package/dist/cjs/foundation/permissionModel.js.map +1 -0
  49. package/dist/cjs/foundation/uploadModel.js +71 -0
  50. package/dist/cjs/foundation/uploadModel.js.map +1 -0
  51. package/dist/cjs/index.js +59 -0
  52. package/dist/cjs/index.js.map +1 -1
  53. package/dist/esm/ComponentName.d.ts +8 -1
  54. package/dist/esm/ComponentName.d.ts.map +1 -1
  55. package/dist/esm/ComponentName.js +7 -0
  56. package/dist/esm/ComponentName.js.map +1 -1
  57. package/dist/esm/defaultBlueprint.js +2 -0
  58. package/dist/esm/defaultBlueprint.js.map +1 -1
  59. package/dist/esm/defaultBlueprintComponentMetadata.js +2 -0
  60. package/dist/esm/defaultBlueprintComponentMetadata.js.map +1 -1
  61. package/dist/esm/defaultBlueprintComponents.d.ts.map +1 -1
  62. package/dist/esm/defaultBlueprintComponents.js +15 -1
  63. package/dist/esm/defaultBlueprintComponents.js.map +1 -1
  64. package/dist/esm/foundation/ActivityFeed.d.ts +3 -0
  65. package/dist/esm/foundation/ActivityFeed.d.ts.map +1 -0
  66. package/dist/esm/foundation/ActivityFeed.js +120 -0
  67. package/dist/esm/foundation/ActivityFeed.js.map +1 -0
  68. package/dist/esm/foundation/ApprovalChainStepper.d.ts +3 -0
  69. package/dist/esm/foundation/ApprovalChainStepper.d.ts.map +1 -0
  70. package/dist/esm/foundation/ApprovalChainStepper.js +128 -0
  71. package/dist/esm/foundation/ApprovalChainStepper.js.map +1 -0
  72. package/dist/esm/foundation/AvatarStack.d.ts +3 -0
  73. package/dist/esm/foundation/AvatarStack.d.ts.map +1 -0
  74. package/dist/esm/foundation/AvatarStack.js +71 -0
  75. package/dist/esm/foundation/AvatarStack.js.map +1 -0
  76. package/dist/esm/foundation/ChecklistSection.d.ts +3 -0
  77. package/dist/esm/foundation/ChecklistSection.d.ts.map +1 -0
  78. package/dist/esm/foundation/ChecklistSection.js +172 -0
  79. package/dist/esm/foundation/ChecklistSection.js.map +1 -0
  80. package/dist/esm/foundation/FileUploader.d.ts +3 -0
  81. package/dist/esm/foundation/FileUploader.d.ts.map +1 -0
  82. package/dist/esm/foundation/FileUploader.js +216 -0
  83. package/dist/esm/foundation/FileUploader.js.map +1 -0
  84. package/dist/esm/foundation/FileUploaderHandler.d.ts +8 -0
  85. package/dist/esm/foundation/FileUploaderHandler.d.ts.map +1 -0
  86. package/dist/esm/foundation/FileUploaderHandler.js +14 -0
  87. package/dist/esm/foundation/FileUploaderHandler.js.map +1 -0
  88. package/dist/esm/foundation/Foundation.stories.d.ts +16 -0
  89. package/dist/esm/foundation/Foundation.stories.d.ts.map +1 -1
  90. package/dist/esm/foundation/Foundation.stories.js +16 -0
  91. package/dist/esm/foundation/Foundation.stories.js.map +1 -1
  92. package/dist/esm/foundation/OrgTree.d.ts +3 -0
  93. package/dist/esm/foundation/OrgTree.d.ts.map +1 -0
  94. package/dist/esm/foundation/OrgTree.js +186 -0
  95. package/dist/esm/foundation/OrgTree.js.map +1 -0
  96. package/dist/esm/foundation/PermissionMatrix.d.ts +3 -0
  97. package/dist/esm/foundation/PermissionMatrix.d.ts.map +1 -0
  98. package/dist/esm/foundation/PermissionMatrix.js +134 -0
  99. package/dist/esm/foundation/PermissionMatrix.js.map +1 -0
  100. package/dist/esm/foundation/activityModel.d.ts +22 -0
  101. package/dist/esm/foundation/activityModel.d.ts.map +1 -0
  102. package/dist/esm/foundation/activityModel.js +58 -0
  103. package/dist/esm/foundation/activityModel.js.map +1 -0
  104. package/dist/esm/foundation/approvalModel.d.ts +27 -0
  105. package/dist/esm/foundation/approvalModel.d.ts.map +1 -0
  106. package/dist/esm/foundation/approvalModel.js +81 -0
  107. package/dist/esm/foundation/approvalModel.js.map +1 -0
  108. package/dist/esm/foundation/avatarModel.d.ts +11 -0
  109. package/dist/esm/foundation/avatarModel.d.ts.map +1 -0
  110. package/dist/esm/foundation/avatarModel.js +38 -0
  111. package/dist/esm/foundation/avatarModel.js.map +1 -0
  112. package/dist/esm/foundation/checklistModel.d.ts +17 -0
  113. package/dist/esm/foundation/checklistModel.d.ts.map +1 -0
  114. package/dist/esm/foundation/checklistModel.js +53 -0
  115. package/dist/esm/foundation/checklistModel.js.map +1 -0
  116. package/dist/esm/foundation/formatting.d.ts +1 -0
  117. package/dist/esm/foundation/formatting.d.ts.map +1 -1
  118. package/dist/esm/foundation/formatting.js +11 -1
  119. package/dist/esm/foundation/formatting.js.map +1 -1
  120. package/dist/esm/foundation/foundationComponentMetadata.d.ts.map +1 -1
  121. package/dist/esm/foundation/foundationComponentMetadata.js +47 -0
  122. package/dist/esm/foundation/foundationComponentMetadata.js.map +1 -1
  123. package/dist/esm/foundation/foundationDescriptors.d.ts.map +1 -1
  124. package/dist/esm/foundation/foundationDescriptors.js +246 -0
  125. package/dist/esm/foundation/foundationDescriptors.js.map +1 -1
  126. package/dist/esm/foundation/foundationSamples.d.ts.map +1 -1
  127. package/dist/esm/foundation/foundationSamples.js +230 -0
  128. package/dist/esm/foundation/foundationSamples.js.map +1 -1
  129. package/dist/esm/foundation/foundationStrings.d.ts +26 -0
  130. package/dist/esm/foundation/foundationStrings.d.ts.map +1 -1
  131. package/dist/esm/foundation/foundationStrings.js +27 -1
  132. package/dist/esm/foundation/foundationStrings.js.map +1 -1
  133. package/dist/esm/foundation/index.d.ts +15 -0
  134. package/dist/esm/foundation/index.d.ts.map +1 -1
  135. package/dist/esm/foundation/index.js +15 -0
  136. package/dist/esm/foundation/index.js.map +1 -1
  137. package/dist/esm/foundation/orgModel.d.ts +20 -0
  138. package/dist/esm/foundation/orgModel.d.ts.map +1 -0
  139. package/dist/esm/foundation/orgModel.js +99 -0
  140. package/dist/esm/foundation/orgModel.js.map +1 -0
  141. package/dist/esm/foundation/permissionModel.d.ts +24 -0
  142. package/dist/esm/foundation/permissionModel.d.ts.map +1 -0
  143. package/dist/esm/foundation/permissionModel.js +77 -0
  144. package/dist/esm/foundation/permissionModel.js.map +1 -0
  145. package/dist/esm/foundation/uploadModel.d.ts +31 -0
  146. package/dist/esm/foundation/uploadModel.d.ts.map +1 -0
  147. package/dist/esm/foundation/uploadModel.js +65 -0
  148. package/dist/esm/foundation/uploadModel.js.map +1 -0
  149. package/dist/esm/index.js +16 -1
  150. package/dist/esm/index.js.map +1 -1
  151. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  152. package/foundation/ActivityFeed.tsx +61 -0
  153. package/foundation/ApprovalChainStepper.tsx +66 -0
  154. package/foundation/AvatarStack.tsx +43 -0
  155. package/foundation/ChecklistSection.tsx +80 -0
  156. package/foundation/FileUploader.tsx +122 -0
  157. package/foundation/FileUploaderHandler.tsx +22 -0
  158. package/foundation/Foundation.stories.tsx +16 -0
  159. package/foundation/OrgTree.tsx +101 -0
  160. package/foundation/PermissionMatrix.tsx +82 -0
  161. package/foundation/activityModel.ts +65 -0
  162. package/foundation/approvalModel.ts +88 -0
  163. package/foundation/avatarModel.ts +36 -0
  164. package/foundation/checklistModel.ts +62 -0
  165. package/foundation/formatting.ts +9 -0
  166. package/foundation/foundationComponentMetadata.ts +7 -0
  167. package/foundation/foundationDescriptors.ts +153 -0
  168. package/foundation/foundationSamples.ts +59 -0
  169. package/foundation/foundationStrings.ts +26 -0
  170. package/foundation/index.ts +15 -0
  171. package/foundation/orgModel.ts +85 -0
  172. package/foundation/permissionModel.ts +85 -0
  173. package/foundation/uploadModel.ts +66 -0
  174. package/package.json +8 -8
  175. package/shell/layout.css +418 -0
@@ -0,0 +1,99 @@
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
+ /** A person or unit in an organization, with who they report to. */ /** Reads nodes out of a property value, dropping entries without an id and keeping the first of a repeated id. */ function readOrgNodes(value) {
4
+ if (!Array.isArray(value)) return [];
5
+ const seen = new Set();
6
+ return value.flatMap((entry)=>{
7
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) return [];
8
+ const { id, label, title, parentId } = entry;
9
+ if (typeof id !== 'string' || id.length === 0 || seen.has(id)) return [];
10
+ seen.add(id);
11
+ return [
12
+ {
13
+ id,
14
+ label: typeof label === 'string' && label.length > 0 ? label : id,
15
+ ...typeof title === 'string' ? {
16
+ title
17
+ } : {},
18
+ ...typeof parentId === 'string' && parentId.length > 0 ? {
19
+ parentId
20
+ } : {}
21
+ }
22
+ ];
23
+ });
24
+ }
25
+ /**
26
+ * Builds the tree from the flat rows a query returns.
27
+ *
28
+ * Someone whose manager is not in the data becomes a root rather than vanishing, and a reporting cycle is broken at the node that closes it
29
+ * - which becomes a root - so malformed data draws something and never loops. Siblings keep the order of the rows.
30
+ */ function buildOrgTree(nodes) {
31
+ const known = new Set(nodes.map((node)=>node.id));
32
+ const parentOf = new Map(nodes.map((node)=>[
33
+ node.id,
34
+ node.parentId !== undefined && known.has(node.parentId) && node.parentId !== node.id ? node.parentId : undefined
35
+ ]));
36
+ for (const node of nodes){
37
+ const path = new Set([
38
+ node.id
39
+ ]);
40
+ for(let current = parentOf.get(node.id); current !== undefined; current = parentOf.get(current)){
41
+ if (path.has(current)) {
42
+ parentOf.set(node.id, undefined);
43
+ break;
44
+ }
45
+ path.add(current);
46
+ }
47
+ }
48
+ const placed = new Map(nodes.map((node)=>[
49
+ node.id,
50
+ {
51
+ ...node,
52
+ children: [],
53
+ depth: 0
54
+ }
55
+ ]));
56
+ const roots = [];
57
+ for (const node of nodes){
58
+ const parent = parentOf.get(node.id);
59
+ if (parent === undefined) roots.push(placed.get(node.id));
60
+ else placed.get(parent).children.push(placed.get(node.id));
61
+ }
62
+ const assignDepth = (level, depth)=>level.forEach((node)=>{
63
+ node.depth = depth;
64
+ assignDepth(node.children, depth + 1);
65
+ });
66
+ assignDepth(roots, 1);
67
+ return roots;
68
+ }
69
+ /** The nodes that can be reached from the roots with the given expansion, in the order they are drawn. */ function visibleNodes(roots, expanded) {
70
+ return roots.flatMap((node)=>[
71
+ node,
72
+ ...expanded.has(node.id) ? visibleNodes(node.children, expanded) : []
73
+ ]);
74
+ }
75
+ /** The ids of every node down to a depth: what is expanded when the tree first opens. */ function expandedToDepth(roots, depth) {
76
+ const result = new Set();
77
+ const walk = (level)=>level.forEach((node)=>{
78
+ if (node.depth < depth && node.children.length > 0) result.add(node.id);
79
+ walk(node.children);
80
+ });
81
+ walk(roots);
82
+ return result;
83
+ }
84
+ /** The number of people below a node, at any depth. */ const descendantCount = (node)=>node.children.reduce((sum, child)=>sum + 1 + descendantCount(child), 0);
85
+ /** For each node, the nodes that share its parent (itself included, in order) and its parent: what a tree needs for its set size and position, and for Left to go up. */ function placements(roots) {
86
+ const result = new Map();
87
+ const walk = (level, parent)=>level.forEach((node)=>{
88
+ result.set(node.id, {
89
+ siblings: level,
90
+ parent
91
+ });
92
+ walk(node.children, node);
93
+ });
94
+ walk(roots);
95
+ return result;
96
+ }
97
+
98
+ export { buildOrgTree, descendantCount, expandedToDepth, placements, readOrgNodes, visibleNodes };
99
+ //# sourceMappingURL=orgModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orgModel.js","sources":["../../../foundation/orgModel.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/** A person or unit in an organization, with who they report to. */\nexport interface OrgNode {\n id: string;\n label: string;\n title?: string;\n parentId?: string;\n}\n\n/** A node placed in the tree. */\nexport interface OrgTreeNode extends OrgNode {\n children: OrgTreeNode[];\n depth: number;\n}\n\n/** Reads nodes out of a property value, dropping entries without an id and keeping the first of a repeated id. */\nexport function readOrgNodes(value: unknown): OrgNode[] {\n if (!Array.isArray(value)) return [];\n\n const seen = new Set<string>();\n return value.flatMap((entry): OrgNode[] => {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) return [];\n const { id, label, title, parentId } = entry as Record<string, unknown>;\n if (typeof id !== 'string' || id.length === 0 || seen.has(id)) return [];\n seen.add(id);\n return [{ id, label: typeof label === 'string' && label.length > 0 ? label : id, ...(typeof title === 'string' ? { title } : {}), ...(typeof parentId === 'string' && parentId.length > 0 ? { parentId } : {}) }];\n });\n}\n\n/**\n * Builds the tree from the flat rows a query returns.\n *\n * Someone whose manager is not in the data becomes a root rather than vanishing, and a reporting cycle is broken at the node that closes it\n * - which becomes a root - so malformed data draws something and never loops. Siblings keep the order of the rows.\n */\nexport function buildOrgTree(nodes: OrgNode[]): OrgTreeNode[] {\n const known = new Set(nodes.map(node => node.id));\n const parentOf = new Map<string, string | undefined>(nodes.map(node => [node.id, node.parentId !== undefined && known.has(node.parentId) && node.parentId !== node.id ? node.parentId : undefined]));\n\n for (const node of nodes) {\n const path = new Set<string>([node.id]);\n for (let current = parentOf.get(node.id); current !== undefined; current = parentOf.get(current)) {\n if (path.has(current)) { parentOf.set(node.id, undefined); break; }\n path.add(current);\n }\n }\n\n const placed = new Map<string, OrgTreeNode>(nodes.map(node => [node.id, { ...node, children: [], depth: 0 }]));\n const roots: OrgTreeNode[] = [];\n for (const node of nodes) {\n const parent = parentOf.get(node.id);\n if (parent === undefined) roots.push(placed.get(node.id)!);\n else placed.get(parent)!.children.push(placed.get(node.id)!);\n }\n\n const assignDepth = (level: OrgTreeNode[], depth: number) => level.forEach(node => { node.depth = depth; assignDepth(node.children, depth + 1); });\n assignDepth(roots, 1);\n return roots;\n}\n\n/** The nodes that can be reached from the roots with the given expansion, in the order they are drawn. */\nexport function visibleNodes(roots: OrgTreeNode[], expanded: ReadonlySet<string>): OrgTreeNode[] {\n return roots.flatMap(node => [node, ...(expanded.has(node.id) ? visibleNodes(node.children, expanded) : [])]);\n}\n\n/** The ids of every node down to a depth: what is expanded when the tree first opens. */\nexport function expandedToDepth(roots: OrgTreeNode[], depth: number): Set<string> {\n const result = new Set<string>();\n const walk = (level: OrgTreeNode[]) => level.forEach(node => { if (node.depth < depth && node.children.length > 0) result.add(node.id); walk(node.children); });\n walk(roots);\n return result;\n}\n\n/** The number of people below a node, at any depth. */\nexport const descendantCount = (node: OrgTreeNode): number => node.children.reduce((sum, child) => sum + 1 + descendantCount(child), 0);\n\n/** For each node, the nodes that share its parent (itself included, in order) and its parent: what a tree needs for its set size and position, and for Left to go up. */\nexport function placements(roots: OrgTreeNode[]): Map<string, { siblings: OrgTreeNode[]; parent?: OrgTreeNode }> {\n const result = new Map<string, { siblings: OrgTreeNode[]; parent?: OrgTreeNode }>();\n const walk = (level: OrgTreeNode[], parent?: OrgTreeNode) => level.forEach(node => { result.set(node.id, { siblings: level, parent }); walk(node.children, node); });\n walk(roots);\n return result;\n}\n"],"names":["readOrgNodes","value","Array","isArray","seen","Set","flatMap","entry","id","label","title","parentId","length","has","add","buildOrgTree","nodes","known","map","node","parentOf","Map","undefined","path","current","get","set","placed","children","depth","roots","parent","push","assignDepth","level","forEach","visibleNodes","expanded","expandedToDepth","result","walk","descendantCount","reduce","sum","child","placements","siblings"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface MatrixRole {
2
+ id: string;
3
+ label: string;
4
+ }
5
+ export interface MatrixPermission {
6
+ id: string;
7
+ label: string;
8
+ group?: string;
9
+ }
10
+ export interface MatrixGrant {
11
+ role: string;
12
+ permission: string;
13
+ }
14
+ export interface MatrixSection {
15
+ group?: string;
16
+ permissions: MatrixPermission[];
17
+ }
18
+ export declare function readRoles(value: unknown): MatrixRole[];
19
+ export declare function readPermissions(value: unknown): MatrixPermission[];
20
+ export declare function readGrants(value: unknown, roles: MatrixRole[], permissions: MatrixPermission[]): MatrixGrant[];
21
+ export declare const isGranted: (grants: MatrixGrant[], role: string, permission: string) => boolean;
22
+ export declare const setGrant: (grants: MatrixGrant[], role: string, permission: string, granted: boolean) => MatrixGrant[];
23
+ export declare function sectionsOf(permissions: MatrixPermission[]): MatrixSection[];
24
+ //# sourceMappingURL=permissionModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionModel.d.ts","sourceRoot":"","sources":["../../../foundation/permissionModel.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACjB;AAGD,MAAM,WAAW,gBAAgB;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAGD,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACtB;AAGD,MAAM,WAAW,aAAa;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACnC;AAMD,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,EAAE,CAOtD;AAGD,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAOlE;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,GAAG,WAAW,EAAE,CAa9G;AAGD,eAAO,MAAM,SAAS,WAAY,WAAW,EAAE,QAAQ,MAAM,cAAc,MAAM,KAAG,OAAuF,CAAC;AAG5K,eAAO,MAAM,QAAQ,WAAY,WAAW,EAAE,QAAQ,MAAM,cAAc,MAAM,WAAW,OAAO,KAAG,WAAW,EACoE,CAAC;AAGrL,wBAAgB,UAAU,CAAC,WAAW,EAAE,gBAAgB,EAAE,GAAG,aAAa,EAAE,CAS3E"}
@@ -0,0 +1,77 @@
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
+ /** A role: a column of the matrix. */ const records = (value)=>Array.isArray(value) ? value.filter((entry)=>typeof entry === 'object' && entry !== null && !Array.isArray(entry)) : [];
4
+ /** Reads roles, dropping those without an id and repeated ids. */ function readRoles(value) {
5
+ const seen = new Set();
6
+ return records(value).flatMap((entry)=>{
7
+ if (typeof entry.id !== 'string' || entry.id.length === 0 || seen.has(entry.id)) return [];
8
+ seen.add(entry.id);
9
+ return [
10
+ {
11
+ id: entry.id,
12
+ label: typeof entry.label === 'string' && entry.label.length > 0 ? entry.label : entry.id
13
+ }
14
+ ];
15
+ });
16
+ }
17
+ /** Reads permissions, dropping those without an id and repeated ids. */ function readPermissions(value) {
18
+ const seen = new Set();
19
+ return records(value).flatMap((entry)=>{
20
+ if (typeof entry.id !== 'string' || entry.id.length === 0 || seen.has(entry.id)) return [];
21
+ seen.add(entry.id);
22
+ return [
23
+ {
24
+ id: entry.id,
25
+ label: typeof entry.label === 'string' && entry.label.length > 0 ? entry.label : entry.id,
26
+ ...typeof entry.group === 'string' && entry.group.length > 0 ? {
27
+ group: entry.group
28
+ } : {}
29
+ }
30
+ ];
31
+ });
32
+ }
33
+ /** 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. */ function readGrants(value, roles, permissions) {
34
+ const roleIds = new Set(roles.map((role)=>role.id));
35
+ const permissionIds = new Set(permissions.map((permission)=>permission.id));
36
+ const seen = new Set();
37
+ return records(value).flatMap((entry)=>{
38
+ const { role, permission } = entry;
39
+ if (typeof role !== 'string' || typeof permission !== 'string' || !roleIds.has(role) || !permissionIds.has(permission)) return [];
40
+ const key = `${role}\u0000${permission}`;
41
+ if (seen.has(key)) return [];
42
+ seen.add(key);
43
+ return [
44
+ {
45
+ role,
46
+ permission
47
+ }
48
+ ];
49
+ });
50
+ }
51
+ /** Whether a role holds a permission. */ const isGranted = (grants, role, permission)=>grants.some((grant)=>grant.role === role && grant.permission === permission);
52
+ /** Grants a permission to a role, or takes it away, leaving every other grant as it was. */ const setGrant = (grants, role, permission, granted)=>granted ? isGranted(grants, role, permission) ? grants : [
53
+ ...grants,
54
+ {
55
+ role,
56
+ permission
57
+ }
58
+ ] : grants.filter((grant)=>!(grant.role === role && grant.permission === permission));
59
+ /** Groups the permissions into runs by their group, in the order first seen, with the ungrouped ones in a run of their own. */ function sectionsOf(permissions) {
60
+ const sections = [];
61
+ for (const permission of permissions){
62
+ const section = sections.find((candidate)=>candidate.group === permission.group);
63
+ if (section) section.permissions.push(permission);
64
+ else sections.push({
65
+ ...permission.group === undefined ? {} : {
66
+ group: permission.group
67
+ },
68
+ permissions: [
69
+ permission
70
+ ]
71
+ });
72
+ }
73
+ return sections;
74
+ }
75
+
76
+ export { isGranted, readGrants, readPermissions, readRoles, sectionsOf, setGrant };
77
+ //# sourceMappingURL=permissionModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissionModel.js","sources":["../../../foundation/permissionModel.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/** A role: a column of the matrix. */\nexport interface MatrixRole {\n id: string;\n label: string;\n}\n\n/** A permission: a row of the matrix, optionally in a named group. */\nexport interface MatrixPermission {\n id: string;\n label: string;\n group?: string;\n}\n\n/** One role holding one permission. */\nexport interface MatrixGrant {\n role: string;\n permission: string;\n}\n\n/** A named run of permissions, for the group heading rows. */\nexport interface MatrixSection {\n group?: string;\n permissions: MatrixPermission[];\n}\n\nconst records = (value: unknown): Record<string, unknown>[] =>\n Array.isArray(value) ? value.filter((entry): entry is Record<string, unknown> => typeof entry === 'object' && entry !== null && !Array.isArray(entry)) : [];\n\n/** Reads roles, dropping those without an id and repeated ids. */\nexport function readRoles(value: unknown): MatrixRole[] {\n const seen = new Set<string>();\n return records(value).flatMap(entry => {\n if (typeof entry.id !== 'string' || entry.id.length === 0 || seen.has(entry.id)) return [];\n seen.add(entry.id);\n return [{ id: entry.id, label: typeof entry.label === 'string' && entry.label.length > 0 ? entry.label : entry.id }];\n });\n}\n\n/** Reads permissions, dropping those without an id and repeated ids. */\nexport function readPermissions(value: unknown): MatrixPermission[] {\n const seen = new Set<string>();\n return records(value).flatMap(entry => {\n if (typeof entry.id !== 'string' || entry.id.length === 0 || seen.has(entry.id)) return [];\n seen.add(entry.id);\n 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 } : {}) }];\n });\n}\n\n/** 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. */\nexport function readGrants(value: unknown, roles: MatrixRole[], permissions: MatrixPermission[]): MatrixGrant[] {\n const roleIds = new Set(roles.map(role => role.id));\n const permissionIds = new Set(permissions.map(permission => permission.id));\n const seen = new Set<string>();\n\n return records(value).flatMap(entry => {\n const { role, permission } = entry;\n if (typeof role !== 'string' || typeof permission !== 'string' || !roleIds.has(role) || !permissionIds.has(permission)) return [];\n const key = `${role}\\u0000${permission}`;\n if (seen.has(key)) return [];\n seen.add(key);\n return [{ role, permission }];\n });\n}\n\n/** Whether a role holds a permission. */\nexport const isGranted = (grants: MatrixGrant[], role: string, permission: string): boolean => grants.some(grant => grant.role === role && grant.permission === permission);\n\n/** Grants a permission to a role, or takes it away, leaving every other grant as it was. */\nexport const setGrant = (grants: MatrixGrant[], role: string, permission: string, granted: boolean): MatrixGrant[] =>\n granted ? (isGranted(grants, role, permission) ? grants : [...grants, { role, permission }]) : grants.filter(grant => !(grant.role === role && grant.permission === permission));\n\n/** Groups the permissions into runs by their group, in the order first seen, with the ungrouped ones in a run of their own. */\nexport function sectionsOf(permissions: MatrixPermission[]): MatrixSection[] {\n const sections: MatrixSection[] = [];\n for (const permission of permissions) {\n const section = sections.find(candidate => candidate.group === permission.group);\n if (section) section.permissions.push(permission);\n else sections.push({ ...(permission.group === undefined ? {} : { group: permission.group }), permissions: [permission] });\n }\n\n return sections;\n}\n"],"names":["records","value","Array","isArray","filter","entry","readRoles","seen","Set","flatMap","id","length","has","add","label","readPermissions","group","readGrants","roles","permissions","roleIds","map","role","permissionIds","permission","key","isGranted","grants","some","grant","setGrant","granted","sectionsOf","sections","section","find","candidate","push","undefined"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ export declare enum UploadStatus {
2
+ Queued = "queued",
3
+ Uploading = "uploading",
4
+ Done = "done",
5
+ Failed = "failed"
6
+ }
7
+ export interface UploadRules {
8
+ accept: string;
9
+ maximumBytes: number;
10
+ multiple: boolean;
11
+ }
12
+ export interface SelectedFile {
13
+ name: string;
14
+ size: number;
15
+ type: string;
16
+ }
17
+ export declare enum UploadRefusal {
18
+ WrongType = "wrongType",
19
+ TooLarge = "tooLarge",
20
+ Single = "single"
21
+ }
22
+ export declare function matchesAccept(file: SelectedFile, accept: string): boolean;
23
+ export declare function checkSelection<T extends SelectedFile>(files: T[], rules: UploadRules, alreadySelected?: number): {
24
+ accepted: T[];
25
+ refused: {
26
+ file: T;
27
+ reason: UploadRefusal;
28
+ }[];
29
+ };
30
+ export declare function formatBytes(bytes: number, locale: string): string;
31
+ //# sourceMappingURL=uploadModel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploadModel.d.ts","sourceRoot":"","sources":["../../../foundation/uploadModel.ts"],"names":[],"mappings":"AAIA,oBAAY,YAAY;IACpB,MAAM,WAAW;IACjB,SAAS,cAAc;IACvB,IAAI,SAAS;IACb,MAAM,WAAW;CACpB;AAGD,MAAM,WAAW,WAAW;IAExB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CACrB;AAGD,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CAChB;AAGD,oBAAY,aAAa;IACrB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,MAAM,WAAW;CACpB;AAGD,wBAAgB,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAOzE;AAGD,wBAAgB,cAAc,CAAC,CAAC,SAAS,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,eAAe,SAAI,GAAG;IAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,MAAM,EAAE,aAAa,CAAA;KAAE,EAAE,CAAA;CAAE,CAY5K;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAMjE"}
@@ -0,0 +1,65 @@
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
+ /** Where a file is in being uploaded. */ var UploadStatus = /*#__PURE__*/ function(UploadStatus) {
4
+ UploadStatus["Queued"] = "queued";
5
+ UploadStatus["Uploading"] = "uploading";
6
+ UploadStatus["Done"] = "done";
7
+ UploadStatus["Failed"] = "failed";
8
+ return UploadStatus;
9
+ }({});
10
+ /** Why a file was refused. */ var UploadRefusal = /*#__PURE__*/ function(UploadRefusal) {
11
+ UploadRefusal["WrongType"] = "wrongType";
12
+ UploadRefusal["TooLarge"] = "tooLarge";
13
+ UploadRefusal["Single"] = "single";
14
+ return UploadRefusal;
15
+ }({});
16
+ /** Whether a file matches an `accept` list; an empty list accepts everything, and matching ignores case. */ function matchesAccept(file, accept) {
17
+ const patterns = accept.split(',').map((pattern)=>pattern.trim().toLowerCase()).filter((pattern)=>pattern.length > 0);
18
+ if (patterns.length === 0) return true;
19
+ const name = file.name.toLowerCase();
20
+ const type = file.type.toLowerCase();
21
+ return patterns.some((pattern)=>pattern.startsWith('.') ? name.endsWith(pattern) : pattern.endsWith('/*') ? type.startsWith(pattern.slice(0, -1)) : type === pattern);
22
+ }
23
+ /** Sorts a selection into the files to take and the reasons for refusing the others. Only the first is taken when one file is allowed. */ function checkSelection(files, rules, alreadySelected = 0) {
24
+ const accepted = [];
25
+ const refused = [];
26
+ for (const file of files){
27
+ if (!matchesAccept(file, rules.accept)) refused.push({
28
+ file,
29
+ reason: "wrongType"
30
+ });
31
+ else if (rules.maximumBytes > 0 && file.size > rules.maximumBytes) refused.push({
32
+ file,
33
+ reason: "tooLarge"
34
+ });
35
+ else if (!rules.multiple && alreadySelected + accepted.length >= 1) refused.push({
36
+ file,
37
+ reason: "single"
38
+ });
39
+ else accepted.push(file);
40
+ }
41
+ return {
42
+ accepted,
43
+ refused
44
+ };
45
+ }
46
+ /** A file size in the largest unit that keeps it under 1024, for the locale. */ function formatBytes(bytes, locale) {
47
+ const units = [
48
+ 'B',
49
+ 'KB',
50
+ 'MB',
51
+ 'GB'
52
+ ];
53
+ let value = bytes;
54
+ let unit = 0;
55
+ while(value >= 1024 && unit < units.length - 1){
56
+ value /= 1024;
57
+ unit++;
58
+ }
59
+ return `${new Intl.NumberFormat(locale, {
60
+ maximumFractionDigits: unit === 0 ? 0 : 1
61
+ }).format(value)} ${units[unit]}`;
62
+ }
63
+
64
+ export { UploadRefusal, UploadStatus, checkSelection, formatBytes, matchesAccept };
65
+ //# sourceMappingURL=uploadModel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uploadModel.js","sources":["../../../foundation/uploadModel.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\n/** Where a file is in being uploaded. */\nexport enum UploadStatus {\n Queued = 'queued',\n Uploading = 'uploading',\n Done = 'done',\n Failed = 'failed',\n}\n\n/** The rules a selection is checked against before anything is sent. */\nexport interface UploadRules {\n /** A comma-separated `accept` list: extensions (`.pdf`), MIME types (`image/png`) and wildcards (`image/*`). */\n accept: string;\n maximumBytes: number;\n multiple: boolean;\n}\n\n/** What the checker needs of a file. */\nexport interface SelectedFile {\n name: string;\n size: number;\n type: string;\n}\n\n/** Why a file was refused. */\nexport enum UploadRefusal {\n WrongType = 'wrongType',\n TooLarge = 'tooLarge',\n Single = 'single',\n}\n\n/** Whether a file matches an `accept` list; an empty list accepts everything, and matching ignores case. */\nexport function matchesAccept(file: SelectedFile, accept: string): boolean {\n const patterns = accept.split(',').map(pattern => pattern.trim().toLowerCase()).filter(pattern => pattern.length > 0);\n if (patterns.length === 0) return true;\n\n const name = file.name.toLowerCase();\n const type = file.type.toLowerCase();\n return patterns.some(pattern => pattern.startsWith('.') ? name.endsWith(pattern) : pattern.endsWith('/*') ? type.startsWith(pattern.slice(0, -1)) : type === pattern);\n}\n\n/** Sorts a selection into the files to take and the reasons for refusing the others. Only the first is taken when one file is allowed. */\nexport function checkSelection<T extends SelectedFile>(files: T[], rules: UploadRules, alreadySelected = 0): { accepted: T[]; refused: { file: T; reason: UploadRefusal }[] } {\n const accepted: T[] = [];\n const refused: { file: T; reason: UploadRefusal }[] = [];\n\n for (const file of files) {\n if (!matchesAccept(file, rules.accept)) refused.push({ file, reason: UploadRefusal.WrongType });\n else if (rules.maximumBytes > 0 && file.size > rules.maximumBytes) refused.push({ file, reason: UploadRefusal.TooLarge });\n else if (!rules.multiple && alreadySelected + accepted.length >= 1) refused.push({ file, reason: UploadRefusal.Single });\n else accepted.push(file);\n }\n\n return { accepted, refused };\n}\n\n/** A file size in the largest unit that keeps it under 1024, for the locale. */\nexport function formatBytes(bytes: number, locale: string): string {\n const units = ['B', 'KB', 'MB', 'GB'];\n let value = bytes;\n let unit = 0;\n while (value >= 1024 && unit < units.length - 1) { value /= 1024; unit++; }\n return `${new Intl.NumberFormat(locale, { maximumFractionDigits: unit === 0 ? 0 : 1 }).format(value)} ${units[unit]}`;\n}\n"],"names":["UploadStatus","UploadRefusal","matchesAccept","file","accept","patterns","split","map","pattern","trim","toLowerCase","filter","length","name","type","some","startsWith","endsWith","slice","checkSelection","files","rules","alreadySelected","accepted","refused","push","reason","maximumBytes","size","multiple","formatBytes","bytes","locale","units","value","unit","Intl","NumberFormat","maximumFractionDigits","format"],"mappings":"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"}
package/dist/esm/index.js CHANGED
@@ -55,7 +55,7 @@ export { LayoutModeSwitcher } from './shell/LayoutModeSwitcher.js';
55
55
  export { formatText, foundationStrings, readFoundationStrings } from './foundation/foundationStrings.js';
56
56
  export { ComponentState, componentStates, readComponentState } from './foundation/ComponentState.js';
57
57
  export { PermissionRule, readPermissionRule } from './foundation/PermissionRule.js';
58
- export { NumberFormat, formatDate, formatNumber, isRightToLeft, readLocale, readNumberFormat } from './foundation/formatting.js';
58
+ export { NumberFormat, formatDate, formatDay, formatNumber, isRightToLeft, readLocale, readNumberFormat } from './foundation/formatting.js';
59
59
  export { FoundationIcon, isFoundationIcon } from './foundation/FoundationIcon.js';
60
60
  export { ActionButton } from './foundation/ActionButton.js';
61
61
  export { EmptyStateView, FoundationFrame } from './foundation/StateFrame.js';
@@ -72,6 +72,21 @@ export { moveColumn, readColumns, toggleColumn, visibleColumnIds } from './found
72
72
  export { ColumnChooser } from './foundation/ColumnChooser.js';
73
73
  export { readViews } from './foundation/viewModel.js';
74
74
  export { SavedViewsMenu, savedViewActionOutput } from './foundation/SavedViewsMenu.js';
75
+ export { completed, doneTaskIds, isOverdue, readChecklist, toggleTask } from './foundation/checklistModel.js';
76
+ export { ChecklistSection } from './foundation/ChecklistSection.js';
77
+ export { ActivityKind, dayOf, groupByDay, readActivity } from './foundation/activityModel.js';
78
+ export { ActivityFeed } from './foundation/ActivityFeed.js';
79
+ export { initialsOf, readPeople, visiblePeople } from './foundation/avatarModel.js';
80
+ export { AvatarStack } from './foundation/AvatarStack.js';
81
+ export { UploadRefusal, UploadStatus, checkSelection, formatBytes, matchesAccept } from './foundation/uploadModel.js';
82
+ export { FileUploaderHandlerProvider, useFileUploaderHandler } from './foundation/FileUploaderHandler.js';
83
+ export { FileUploader } from './foundation/FileUploader.js';
84
+ export { ApprovalState, ChainOutcome, chainOutcome, effectiveSteps, readSteps } from './foundation/approvalModel.js';
85
+ export { ApprovalChainStepper } from './foundation/ApprovalChainStepper.js';
86
+ export { buildOrgTree, descendantCount, expandedToDepth, placements, readOrgNodes, visibleNodes } from './foundation/orgModel.js';
87
+ export { OrgTree } from './foundation/OrgTree.js';
88
+ export { isGranted, readGrants, readPermissions, readRoles, sectionsOf, setGrant } from './foundation/permissionModel.js';
89
+ export { PermissionMatrix } from './foundation/PermissionMatrix.js';
75
90
  export { bindable, foundationDescriptors, list, standardStateProperties } from './foundation/foundationDescriptors.js';
76
91
  export { foundationComponentMetadata } from './foundation/foundationComponentMetadata.js';
77
92
  export { foundationElement, foundationSamples } from './foundation/foundationSamples.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}