@tumaet/prompt-shared-state 1.0.10 → 1.0.13

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 (2) hide show
  1. package/README.md +194 -96
  2. package/package.json +9 -9
package/README.md CHANGED
@@ -1,104 +1,202 @@
1
- # prompt-shared-state
2
- A shared library for the **AET Prompt2** system that provides common interfaces and state management (via [Zustand](https://github.com/pmndrs/zustand)) across multiple microfrontends.
1
+ # prompt-shared-state
3
2
 
4
- ## Overview
5
- The **prompt-shared-state** package is designed to help multiple microfrontends share:
6
- - **Data** and **state** through a global [Zustand](https://github.com/pmndrs/zustand) store.
7
- - **Common TypeScript interfaces** for consistent data modeling
3
+ A shared library for the **AET Prompt** system that provides common TypeScript interfaces and state management (via [Zustand](https://github.com/pmndrs/zustand)) across multiple microfrontends.
8
4
 
9
- By using this library, you ensure that all microfrontends reference the same store instance and interfaces, avoiding inconsistencies and duplication.
5
+ ## Overview
10
6
 
11
- ## Features
12
- - **Shared Interfaces**: Commonly used interfaces that can be referenced by any microfrontend, ensuring a single source of truth for data structures. These shall also reflect the data structures used by the core API.
13
- - **Global State Management**: A single Zustand store instance shared across microfrontends.
14
- - **Easy Integration**: Works seamlessly with Module Federation (Webpack 5), Yarn, and npm.
7
+ The **prompt-shared-state** package ensures that all microfrontends share:
15
8
 
16
- ## Installation
17
- Install the package with your preferred package manager:
9
+ - **Global state** through Zustand stores for authentication, course management, and more
10
+ - **Common TypeScript interfaces** for consistent data modeling that mirrors the core API
18
11
 
19
- ```bash
20
- # Using Yarn
21
- yarn add @tumaet/prompt-shared-state
12
+ By using this library, all microfrontends reference the same store instances and type definitions, eliminating state inconsistencies and data model duplication.
22
13
 
23
- # Or using npm
24
- npm install @tumaet/prompt-shared-state
14
+ ## Installation
15
+
16
+ ```bash
17
+ # Using Yarn
18
+ yarn add @tumaet/prompt-shared-state
19
+
20
+ # Using npm
21
+ npm install @tumaet/prompt-shared-state
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Zustand Stores
27
+
28
+ ### useAuthStore
29
+
30
+ Manages authentication state and user permissions.
31
+
32
+ ```tsx
33
+ import { useAuthStore } from '@tumaet/prompt-shared-state'
34
+
35
+ function MyComponent() {
36
+ const { user, permissions, setUser, logout } = useAuthStore()
37
+
38
+ return (
39
+ <div>
40
+ <p>Logged in as: {user?.firstName} {user?.lastName}</p>
41
+ <button onClick={() => logout()}>Log out</button>
42
+ </div>
43
+ )
44
+ }
45
+ ```
46
+
47
+ **State & Actions:**
48
+
49
+ | Name | Type | Description |
50
+ |---|---|---|
51
+ | `user` | `User \| undefined` | The currently authenticated user |
52
+ | `permissions` | `string[]` | List of permission strings for the current user |
53
+ | `setUser(user)` | `(user: User) => void` | Set the authenticated user |
54
+ | `clearUser()` | `() => void` | Clear the current user |
55
+ | `setPermissions(permissions)` | `(permissions: string[]) => void` | Set user permissions |
56
+ | `clearPermissions()` | `() => void` | Clear all permissions |
57
+ | `logout(redirectUri?)` | `(redirectUri?: string) => void` | Log out and optionally redirect |
58
+ | `setLogoutFunction(fn)` | `(logoutFunction: (redirectUri?: string) => void) => void` | Register the logout handler |
59
+
60
+ ---
61
+
62
+ ### useCourseStore
63
+
64
+ Manages course data and the currently selected course. Course selection is persisted to localStorage.
65
+
66
+ ```tsx
67
+ import { useCourseStore } from '@tumaet/prompt-shared-state'
68
+
69
+ function CourseSelector() {
70
+ const { courses, getSelectedCourseID, setSelectedCourseID } = useCourseStore()
71
+
72
+ return (
73
+ <select
74
+ value={getSelectedCourseID() ?? ''}
75
+ onChange={(e) => setSelectedCourseID(e.target.value)}
76
+ >
77
+ {courses.map((course) => (
78
+ <option key={course.id} value={course.id}>
79
+ {course.name}
80
+ </option>
81
+ ))}
82
+ </select>
83
+ )
84
+ }
85
+ ```
86
+
87
+ **State & Actions:**
88
+
89
+ | Name | Type | Description |
90
+ |---|---|---|
91
+ | `courses` | `Course[]` | All available courses |
92
+ | `ownCourseIDs` | `string[]` | IDs of courses the user is enrolled in |
93
+ | `setCourses(courses)` | `(courses: Course[]) => void` | Set the full course list |
94
+ | `setOwnCourseIDs(ids)` | `(ids: string[]) => void` | Set IDs of the user's own courses |
95
+ | `getSelectedCourseID()` | `() => string \| null` | Get the currently selected course ID |
96
+ | `setSelectedCourseID(id)` | `(id: string) => void` | Select a course (persisted to localStorage) |
97
+ | `removeSelectedCourseID()` | `() => void` | Clear the selected course |
98
+ | `isStudentOfCourse(id)` | `(id: string) => boolean` | Check if the user is a student in a course |
99
+ | `updateCourse(id, patch)` | `(id: string, patch: Partial<Course>) => void` | Partially update a course |
100
+
101
+ ---
102
+
103
+ ## TypeScript Interfaces
104
+
105
+ All interfaces are exported from the package root and organized into categories:
106
+
107
+ ```ts
108
+ import {
109
+ Course,
110
+ Student,
111
+ User,
112
+ CoursePhaseWithMetaData,
113
+ PassStatus,
114
+ Role,
115
+ ScoreLevel,
116
+ } from '@tumaet/prompt-shared-state'
25
117
  ```
26
118
 
27
- ## Usage
28
- ### Shared Interfaces
29
- All TypeScript interfaces needed by multiple microfrontends reside here. For example:
30
-
31
- ```ts
32
- import { SomeSharedInterface } from '@tumaet/prompt-shared-state';
33
-
34
- // Use this interface in your code const data: SomeSharedInterface = { // ... };
35
- ```
36
- **Note**: If an interface is only relevant to one microfrontend, keep it local to that microfrontend rather than placing it here.
37
-
38
- ### Global Zustand Store
39
- The package provides a shared Zustand store that can be imported and used by any microfrontend. For example:
40
-
41
- ```ts
42
- import { useSharedStore } from '@tumaet/prompt-shared-state';
43
-
44
- function MyComponent() {
45
- const [sharedValue, setSharedValue] = useSharedStore((state) => [
46
- state.sharedValue, state.setSharedValue,
47
- ]);
48
-
49
- return (
50
- <div>
51
- <p>Shared Value: {sharedValue}</p>
52
- <button onClick={() => setSharedValue('New Value')}>
53
- Update Shared Value
54
- </button>
55
- </div>
56
- );
57
- }
58
- ```
59
- Any changes to the store will be reflected across all microfrontends using this library.
60
-
61
- ### Module Federation Configuration
62
- For the state to be truly _shared_ among all microfrontends, configure **Module Federation** to treat `@tumaet/prompt-shared-state` as a singleton:
63
-
64
- ```js
65
- new ModuleFederationPlugin({
66
- name: 'your-module',
67
- shared: {
68
- '@tumaet/prompt-shared-state': {
69
- singleton: true,
70
- requiredVersion: deps['@tumaet/prompt-shared-state'],
71
- },
72
- // ...other shared dependencies
73
- },
74
- });
75
- ```
76
- This ensures there is only **one** instance of the shared state library at runtime.
77
-
78
- ## Best Practices
79
- 1. **Store Only Truly Shared Data** Keep only data in the global Zustand store that needs to be accessed by multiple microfrontends.
80
- 2. **Keep Interfaces Organized** Place only _truly global_ interfaces in this package. Any interface specific to a single module should remain in that module.
81
- 3. **Version Synchronization** Make sure all microfrontends use the same version of the shared package to avoid any incompatibilities.
82
- 4. **Avoid Overexposing State** If you have sensitive or security-related information, think carefully about whether it needs to be available globally. ---
83
-
84
- ## Publishing Process
85
-
86
- As a member of the AET team, please contribute your changes by creating a pull request.
87
- Once your changes are reviewed and merged into the `main` branch, a GitHub workflow will automatically:
88
-
89
- 1. Bump the package version (according to the keyword in your commit message).
90
- 2. Publish the updated package to the npm registry.
91
-
92
- ### Commit Message Keywords
93
- Include **one** of the following keywords in your commit message to indicate how the version should be bumped:
94
-
95
- - **major**
96
- - Increments the major version (e.g. `1.2.3` → `2.0.0`).
97
- - **minor**
98
- - Increments the minor version (e.g. `1.2.3` → `1.3.0`).
99
- - **(no keyword) or "patch"**
100
- - Increments the patch version by default (e.g. `1.2.3` `1.2.4`).
101
-
102
- If you do not include `major` or `minor` in your commit message, the workflow will assume a **patch** update.
103
-
104
- When the publishing worked, then a PR with a new version number has been opened. This shall be merged immediately.
119
+ ### Available Interfaces
120
+
121
+ | Category | Key Exports | Description |
122
+ |---|---|---|
123
+ | **Course** | `Course`, `UpdateCourse`, `CourseType` | Course data and operations |
124
+ | **Course Phase** | `CoursePhaseWithMetaData`, `CoursePhaseWithType`, `CreateCoursePhase`, `UpdateCoursePhase` | Course phase data and operations |
125
+ | **Course Phase Type** | `CoursePhaseType`, `CoursePhaseTypeMetaDataItem` | Phase type metadata |
126
+ | **Course Phase Participation** | `CoursePhaseParticipationWithStudent`, `CoursePhaseParticipationsWithResolution`, `UpdateCoursePhaseParticipation`, `UpdateCoursePhaseParticipationStatus` | Student participation in phases |
127
+ | **Student** | `Student`, `Gender`, `StudyDegree` | Student profile data |
128
+ | **User** | `User` | Authenticated user data |
129
+ | **Person** | `Person` | Base person interface |
130
+ | **Roles** | `Role`, `getPermissionString` | Role enum and permission utilities |
131
+ | **Assessment** | `ScoreLevel`, `mapScoreLevelToNumber`, `mapNumberToScoreLevel` | Assessment score levels and mapping |
132
+ | **Mailing** | `CourseMailingSettings`, `CoursePhaseMailingConfigData`, `MailingReport`, `SendStatusMail` | Email configuration and reporting |
133
+ | **Application** | `ExportedApplicationAnswer` | Application submission data |
134
+ | **Team** | `Team` | Team definitions |
135
+
136
+ ### Score Levels
137
+
138
+ ```ts
139
+ import { ScoreLevel, mapScoreLevelToNumber, mapNumberToScoreLevel } from '@tumaet/prompt-shared-state'
140
+
141
+ // Enum values: VeryGood, Good, Ok, Bad, VeryBad
142
+ const level = ScoreLevel.Good
143
+ const numeric = mapScoreLevelToNumber(ScoreLevel.Good) // → number
144
+ const back = mapNumberToScoreLevel(numeric) // ScoreLevel
145
+ ```
146
+
147
+ ### Roles
148
+
149
+ ```ts
150
+ import { Role } from '@tumaet/prompt-shared-state'
151
+
152
+ // Enum members: PROMPT_ADMIN, PROMPT_LECTURER, COURSE_LECTURER, COURSE_EDITOR, COURSE_STUDENT
153
+ if (user.role === Role.PROMPT_ADMIN) {
154
+ // show admin UI
155
+ }
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Module Federation Configuration
161
+
162
+ For the state to be truly shared across all microfrontends, configure **Module Federation** to treat `@tumaet/prompt-shared-state` as a singleton:
163
+
164
+ ```js
165
+ new ModuleFederationPlugin({
166
+ name: 'your-module',
167
+ shared: {
168
+ '@tumaet/prompt-shared-state': {
169
+ singleton: true,
170
+ requiredVersion: deps['@tumaet/prompt-shared-state'],
171
+ },
172
+ // ...other shared dependencies
173
+ },
174
+ })
175
+ ```
176
+
177
+ This ensures there is only **one** instance of the shared state library at runtime. Without this, each microfrontend would have its own store and state changes would not propagate across apps.
178
+
179
+ ---
180
+
181
+ ## Best Practices
182
+
183
+ 1. **Store only truly shared data** — Only add state to Zustand stores that needs to be accessed by multiple microfrontends. Keep module-local state in the microfrontend itself.
184
+ 2. **Keep interfaces organized** — Only place interfaces in this package if they are used across multiple microfrontends. Module-specific interfaces should stay in that module.
185
+ 3. **Synchronize versions** All microfrontends should use the same version of this package to avoid type and runtime incompatibilities.
186
+ 4. **Avoid overexposing sensitive state** — Think carefully before storing security-sensitive data in a globally shared store.
187
+
188
+ ---
189
+
190
+ ## Contributing
191
+
192
+ Contribute changes by opening a pull request in this repository. Once merged, create a GitHub Release for the version you want to publish.
193
+
194
+ ### Versioning & Publishing
195
+
196
+ Publishing is triggered by creating a **GitHub Release**. The steps are:
197
+
198
+ 1. Update the version in `package.json` so it matches the intended release tag.
199
+ 2. Create a GitHub Release with the tag `v{version}` (for example, `v1.2.3`).
200
+ 3. The publish workflow validates the tag/version match, builds the package, and publishes it to npm.
201
+
202
+ This package is published independently from `@tumaet/prompt-ui-components`.
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@tumaet/prompt-shared-state",
3
- "version": "1.0.10",
3
+ "version": "1.0.13",
4
4
  "repository": {
5
5
  "type": "git",
6
- "url": "git+https://github.com/ls1intum/prompt-lib.git"
6
+ "url": "git+https://github.com/prompt-edu/prompt-shared-state.git"
7
7
  },
8
8
  "main": "./dist/index.js",
9
9
  "module": "./dist/index.js",
@@ -21,19 +21,19 @@
21
21
  "build": "yarn build:esm",
22
22
  "lint": "eslint \"**/*.{js,jsx,ts,tsx}\""
23
23
  },
24
- "packageManager": "yarn@4.13.0",
24
+ "packageManager": "yarn@4.14.1",
25
25
  "dependencies": {
26
26
  "typescript": "^5.9.3",
27
27
  "zustand": "^5.0.12"
28
28
  },
29
29
  "devDependencies": {
30
- "@eslint/compat": "^2.0.3",
31
- "@typescript-eslint/eslint-plugin": "^8.57.1",
32
- "@typescript-eslint/parser": "^8.57.1",
33
- "eslint": "^10.1.0",
30
+ "@typescript-eslint/eslint-plugin": "^8.59.0",
31
+ "@typescript-eslint/parser": "^8.59.0",
32
+ "eslint": "^10.2.1",
34
33
  "eslint-plugin-prettier": "^5.5.5",
35
34
  "eslint-plugin-react": "^7.37.5",
36
- "eslint-plugin-react-hooks": "^7.0.1",
37
- "prettier": "^3.8.1"
35
+ "eslint-plugin-react-hooks": "^7.1.1",
36
+ "globals": "^17.5.0",
37
+ "prettier": "^3.8.3"
38
38
  }
39
39
  }