placementt-core 1.400.1035 → 1.400.1036

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.
@@ -13,51 +13,24 @@ import { InstituteData } from "./typeDefinitions";
13
13
  * parents in it — so this is a hook: the count is a query, and the answer arrives
14
14
  * a tick after the flags do.
15
15
  */
16
- /** The product a surface can gate on. */
17
16
  export type ProductKey = "wex" | "network" | "parents" | "events" | "skills" | "activities" | "destinations" | "alumni";
18
17
  export type ResolvedProducts = Record<ProductKey, boolean> & {
19
- /** How many parents are actually in the database, across `options.oIds`.
20
- * `parents` is just this over zero; the number is surfaced so a caller that
21
- * wants to show the count doesn't run the same aggregate a second time.
22
- * Zero until the count lands, the same as the flag. */
18
+ employerEvents: boolean;
23
19
  parentCount: number;
24
- /** Package shape, so callers stop testing `package ===` themselves. */
25
20
  isTrust: boolean;
26
21
  isHub: boolean;
27
22
  isHubSchool: boolean;
28
- /** Whether the account holds students, cohorts and placements of its own —
29
- * every package except the two hub-side ones, which consume a hub's. */
30
23
  runsOwnStudents: boolean;
31
- /** An approved careersHubLinks entry — a school inside someone else's hub. */
32
24
  hubLinked: boolean;
33
- /** Ids of the hubs this institute has accepted. Empty unless hubLinked. */
34
25
  hubIds: string[];
35
- /** Products resolved true, in display order. `length` drives the home's
36
- * single-product vs multi-product layout. */
37
26
  enabled: ProductKey[];
38
27
  };
39
- /** Just enough of InstituteData to resolve, so callers can pass partials
40
- * (a trust school row, a customer-success record) without casting. */
41
28
  export type ProductResolverInput = Partial<Pick<InstituteData, "package" | "workExperience" | "employerEvents" | "network" | "careersEvents" | "skillsAssessmentsProduct" | "trackExtracurriculars" | "destinationTracking" | "alumniManagement" | "careersHubLinks">>;
42
- /**
43
- * Resolve an institute's products from its flags alone.
44
- *
45
- * The synchronous half of {@link useProductResolver}, for the code that can't
46
- * hold a hook — task and tip callbacks, backend cron, anything outside React.
47
- * Everything but `parents` is a pure read of the flags; the parent count is a
48
- * query, so a caller that has already run it passes it in and a caller that
49
- * hasn't gets `parents: false`.
50
- *
51
- * @param {ProductResolverInput} [institute] the institute, or a partial of it.
52
- * @param {object} [options] extra context.
53
- * @param {ProductResolverInput[]} [options.trustSchools] schools beneath a trust.
54
- * A trust shows a product when any of its schools has it, matching the nav's
55
- * existing destinations rule.
56
- * @param {number} [options.parentCount] parents already counted, if known.
57
- * @return {ResolvedProducts} what this institute has.
58
- */
29
+ export type TrustSchools = ProductResolverInput[] | {
30
+ [oId: string]: ProductResolverInput;
31
+ };
59
32
  export declare function resolveProducts(institute?: ProductResolverInput, options?: {
60
- trustSchools?: ProductResolverInput[];
33
+ trustSchools?: TrustSchools;
61
34
  parentCount?: number;
62
35
  }): ResolvedProducts;
63
36
  /**
@@ -67,12 +40,12 @@ export declare function resolveProducts(institute?: ProductResolverInput, option
67
40
  * @param {object} [options] extra context.
68
41
  * @param {string[]} [options.oIds] whose parent database to count. A trust holds
69
42
  * none on its own oId, so pass its schools'.
70
- * @param {ProductResolverInput[]} [options.trustSchools] schools beneath a trust.
43
+ * @param {TrustSchools} [options.trustSchools] schools beneath a trust.
71
44
  * @return {ResolvedProducts} what this institute has.
72
45
  */
73
46
  export declare function useProductResolver(institute?: ProductResolverInput, options?: {
74
47
  oIds?: string[];
75
- trustSchools?: ProductResolverInput[];
48
+ trustSchools?: TrustSchools;
76
49
  }): ResolvedProducts;
77
50
  /** Human labels, for checklists, settings and the trust product strip. */
78
51
  export declare const PRODUCT_LABELS: Record<ProductKey, string>;
@@ -9,27 +9,10 @@ exports.useProductResolver = useProductResolver;
9
9
  const react_1 = require("react");
10
10
  const firestore_1 = require("firebase/firestore");
11
11
  const firebaseQuery_1 = __importDefault(require("./firebase/firebaseQuery"));
12
+ const asList = (schools) => Array.isArray(schools) ? schools : Object.values(schools || {});
12
13
  const PRODUCT_ORDER = ["wex", "destinations", "events", "skills", "activities", "network", "parents", "alumni"];
13
- /** Opt-out flag: undefined means on, only an explicit `false` switches it off. */
14
14
  const on = (flag) => flag !== false;
15
15
  const firebaseQuery = new firebaseQuery_1.default();
16
- /**
17
- * Resolve an institute's products from its flags alone.
18
- *
19
- * The synchronous half of {@link useProductResolver}, for the code that can't
20
- * hold a hook — task and tip callbacks, backend cron, anything outside React.
21
- * Everything but `parents` is a pure read of the flags; the parent count is a
22
- * query, so a caller that has already run it passes it in and a caller that
23
- * hasn't gets `parents: false`.
24
- *
25
- * @param {ProductResolverInput} [institute] the institute, or a partial of it.
26
- * @param {object} [options] extra context.
27
- * @param {ProductResolverInput[]} [options.trustSchools] schools beneath a trust.
28
- * A trust shows a product when any of its schools has it, matching the nav's
29
- * existing destinations rule.
30
- * @param {number} [options.parentCount] parents already counted, if known.
31
- * @return {ResolvedProducts} what this institute has.
32
- */
33
16
  function resolveProducts(institute, options) {
34
17
  const parentCount = options?.parentCount || 0;
35
18
  const i = institute || {};
@@ -40,21 +23,21 @@ function resolveProducts(institute, options) {
40
23
  // Hub and hub-school accounts don't run their own work experience or skills;
41
24
  // they consume the hub's events and employer network.
42
25
  const runsOwnStudents = !isHub && !isHubSchool;
43
- // `employerEvents` is the billing container the events, skills and
44
- // extracurricular modules hang off. A hub gets the events module by package.
45
- const eventsContainer = Boolean(i.employerEvents) || isHub;
46
- const schools = options?.trustSchools || [];
26
+ const schools = asList(options?.trustSchools);
47
27
  /** A trust has a product if it has it itself, or any of its schools does. */
48
28
  const orSchools = (self, pick) => self || (isTrust && schools.some(pick));
29
+ // `employerEvents` is the billing container the events, skills and
30
+ // extracurricular modules hang off. A hub gets the events module by package.
31
+ const eventsContainer = orSchools(Boolean(i.employerEvents) || isHub, (s) => Boolean(s.employerEvents));
49
32
  const wex = orSchools(runsOwnStudents && i.workExperience === true, (s) => s.workExperience === true);
50
33
  const destinations = orSchools(i.destinationTracking === true, (s) => s.destinationTracking === true);
51
34
  const alumni = orSchools(i.alumniManagement === true, (s) => s.alumniManagement === true);
52
35
  const events = orSchools(eventsContainer && on(i.careersEvents), (s) => Boolean(s.employerEvents) && on(s.careersEvents));
53
36
  const skills = orSchools(runsOwnStudents && eventsContainer && on(i.skillsAssessmentsProduct), (s) => Boolean(s.employerEvents) && on(s.skillsAssessmentsProduct));
54
37
  const activities = orSchools(runsOwnStudents && eventsContainer && on(i.trackExtracurriculars), (s) => Boolean(s.employerEvents) && on(s.trackExtracurriculars));
55
- // Opt-out and ungated: every institute gets the employer network unless it is
56
- // explicitly switched off. Matches Institutes.tsx and the staff home today.
57
- const network = on(i.network);
38
+ // Opt-out: every institute gets the employer network unless it is explicitly
39
+ // switched off. A trust keeps it while any of its schools still has it.
40
+ const network = orSchools(on(i.network), (s) => on(s.network));
58
41
  // No flag: the database exists if anyone is in it.
59
42
  const parents = parentCount > 0;
60
43
  const hubIds = Object.entries(i.careersHubLinks || {})
@@ -63,6 +46,7 @@ function resolveProducts(institute, options) {
63
46
  const products = { wex, network, parents, events, skills, activities, destinations, alumni };
64
47
  return {
65
48
  ...products,
49
+ employerEvents: eventsContainer,
66
50
  parentCount,
67
51
  isTrust,
68
52
  isHub,
@@ -80,7 +64,7 @@ function resolveProducts(institute, options) {
80
64
  * @param {object} [options] extra context.
81
65
  * @param {string[]} [options.oIds] whose parent database to count. A trust holds
82
66
  * none on its own oId, so pass its schools'.
83
- * @param {ProductResolverInput[]} [options.trustSchools] schools beneath a trust.
67
+ * @param {TrustSchools} [options.trustSchools] schools beneath a trust.
84
68
  * @return {ResolvedProducts} what this institute has.
85
69
  */
86
70
  function useProductResolver(institute, options) {
@@ -1 +1 @@
1
- {"version":3,"file":"productResolver.js","sourceRoot":"","sources":["../src/productResolver.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"productResolver.js","sourceRoot":"","sources":["../src/productResolver.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "private": false,
3
3
  "name": "placementt-core",
4
4
  "author": "Placementt",
5
- "version": "1.400.1035",
5
+ "version": "1.400.1036",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
8
8
  "scripts": {
@@ -18,67 +18,41 @@ import {InstituteData} from "./typeDefinitions";
18
18
  * a tick after the flags do.
19
19
  */
20
20
 
21
- /** The product a surface can gate on. */
22
21
  export type ProductKey =
23
22
  "wex"|"network"|"parents"|"events"|"skills"|"activities"|"destinations"|"alumni";
24
23
 
25
24
  export type ResolvedProducts = Record<ProductKey, boolean> & {
26
- /** How many parents are actually in the database, across `options.oIds`.
27
- * `parents` is just this over zero; the number is surfaced so a caller that
28
- * wants to show the count doesn't run the same aggregate a second time.
29
- * Zero until the count lands, the same as the flag. */
25
+ employerEvents: boolean,
30
26
  parentCount: number,
31
- /** Package shape, so callers stop testing `package ===` themselves. */
32
27
  isTrust: boolean,
33
28
  isHub: boolean,
34
29
  isHubSchool: boolean,
35
- /** Whether the account holds students, cohorts and placements of its own —
36
- * every package except the two hub-side ones, which consume a hub's. */
37
30
  runsOwnStudents: boolean,
38
- /** An approved careersHubLinks entry — a school inside someone else's hub. */
39
31
  hubLinked: boolean,
40
- /** Ids of the hubs this institute has accepted. Empty unless hubLinked. */
41
32
  hubIds: string[],
42
- /** Products resolved true, in display order. `length` drives the home's
43
- * single-product vs multi-product layout. */
44
33
  enabled: ProductKey[],
45
34
  };
46
35
 
47
- /** Just enough of InstituteData to resolve, so callers can pass partials
48
- * (a trust school row, a customer-success record) without casting. */
49
36
  export type ProductResolverInput = Partial<Pick<InstituteData,
50
37
  "package"|"workExperience"|"employerEvents"|"network"|"careersEvents"|
51
38
  "skillsAssessmentsProduct"|"trackExtracurriculars"|"destinationTracking"|
52
39
  "alumniManagement"|"careersHubLinks">>;
53
40
 
41
+ export type TrustSchools = ProductResolverInput[]|{[oId: string]: ProductResolverInput};
42
+
43
+ const asList = (schools?: TrustSchools): ProductResolverInput[] =>
44
+ Array.isArray(schools) ? schools : Object.values(schools || {});
45
+
54
46
  const PRODUCT_ORDER: ProductKey[] =
55
47
  ["wex", "destinations", "events", "skills", "activities", "network", "parents", "alumni"];
56
48
 
57
- /** Opt-out flag: undefined means on, only an explicit `false` switches it off. */
58
49
  const on = (flag?: boolean) => flag !== false;
59
50
 
60
51
  const firebaseQuery = new FirebaseQuery();
61
52
 
62
- /**
63
- * Resolve an institute's products from its flags alone.
64
- *
65
- * The synchronous half of {@link useProductResolver}, for the code that can't
66
- * hold a hook — task and tip callbacks, backend cron, anything outside React.
67
- * Everything but `parents` is a pure read of the flags; the parent count is a
68
- * query, so a caller that has already run it passes it in and a caller that
69
- * hasn't gets `parents: false`.
70
- *
71
- * @param {ProductResolverInput} [institute] the institute, or a partial of it.
72
- * @param {object} [options] extra context.
73
- * @param {ProductResolverInput[]} [options.trustSchools] schools beneath a trust.
74
- * A trust shows a product when any of its schools has it, matching the nav's
75
- * existing destinations rule.
76
- * @param {number} [options.parentCount] parents already counted, if known.
77
- * @return {ResolvedProducts} what this institute has.
78
- */
79
53
  export function resolveProducts(
80
54
  institute?: ProductResolverInput,
81
- options?: {trustSchools?: ProductResolverInput[], parentCount?: number},
55
+ options?: {trustSchools?: TrustSchools, parentCount?: number},
82
56
  ): ResolvedProducts {
83
57
  const parentCount = options?.parentCount || 0;
84
58
  const i = institute || {};
@@ -92,17 +66,19 @@ export function resolveProducts(
92
66
  // they consume the hub's events and employer network.
93
67
  const runsOwnStudents = !isHub && !isHubSchool;
94
68
 
95
- // `employerEvents` is the billing container the events, skills and
96
- // extracurricular modules hang off. A hub gets the events module by package.
97
- const eventsContainer = Boolean(i.employerEvents) || isHub;
98
-
99
- const schools = options?.trustSchools || [];
69
+ const schools = asList(options?.trustSchools);
100
70
  /** A trust has a product if it has it itself, or any of its schools does. */
101
71
  const orSchools = (
102
72
  self: boolean,
103
73
  pick: (s: ProductResolverInput) => boolean,
104
74
  ) => self || (isTrust && schools.some(pick));
105
75
 
76
+ // `employerEvents` is the billing container the events, skills and
77
+ // extracurricular modules hang off. A hub gets the events module by package.
78
+ const eventsContainer = orSchools(
79
+ Boolean(i.employerEvents) || isHub,
80
+ (s) => Boolean(s.employerEvents));
81
+
106
82
  const wex = orSchools(
107
83
  runsOwnStudents && i.workExperience === true,
108
84
  (s) => s.workExperience === true);
@@ -127,9 +103,9 @@ export function resolveProducts(
127
103
  runsOwnStudents && eventsContainer && on(i.trackExtracurriculars),
128
104
  (s) => Boolean(s.employerEvents) && on(s.trackExtracurriculars));
129
105
 
130
- // Opt-out and ungated: every institute gets the employer network unless it is
131
- // explicitly switched off. Matches Institutes.tsx and the staff home today.
132
- const network = on(i.network);
106
+ // Opt-out: every institute gets the employer network unless it is explicitly
107
+ // switched off. A trust keeps it while any of its schools still has it.
108
+ const network = orSchools(on(i.network), (s) => on(s.network));
133
109
 
134
110
  // No flag: the database exists if anyone is in it.
135
111
  const parents = parentCount > 0;
@@ -143,6 +119,7 @@ export function resolveProducts(
143
119
 
144
120
  return {
145
121
  ...products,
122
+ employerEvents: eventsContainer,
146
123
  parentCount,
147
124
  isTrust,
148
125
  isHub,
@@ -161,12 +138,12 @@ export function resolveProducts(
161
138
  * @param {object} [options] extra context.
162
139
  * @param {string[]} [options.oIds] whose parent database to count. A trust holds
163
140
  * none on its own oId, so pass its schools'.
164
- * @param {ProductResolverInput[]} [options.trustSchools] schools beneath a trust.
141
+ * @param {TrustSchools} [options.trustSchools] schools beneath a trust.
165
142
  * @return {ResolvedProducts} what this institute has.
166
143
  */
167
144
  export function useProductResolver(
168
145
  institute?: ProductResolverInput,
169
- options?: {oIds?: string[], trustSchools?: ProductResolverInput[]},
146
+ options?: {oIds?: string[], trustSchools?: TrustSchools},
170
147
  ): ResolvedProducts {
171
148
  const [parentCount, setParentCount] = useState(0);
172
149