@skysoftware-co/bayan-core-widgets-ui 0.0.6 → 0.0.8
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/.editorconfig +17 -0
- package/.github/copilot/WidgetDevelopmentGuide.md +632 -0
- package/.github/copilot/WidgetProjectStructure.md +81 -0
- package/.github/copilot/git.md +176 -0
- package/.github/copilot/guideline.md +466 -0
- package/.github/copilot-instructions.md +697 -0
- package/.github/prompts/As world class developer, create unit tests for.prompt.md +7 -0
- package/README.md +1 -337
- package/Web.config +7 -0
- package/angular.json +43 -0
- package/package.json +54 -31
- package/projects/bayan-core-ui/README.md +522 -0
- package/projects/bayan-core-ui/package.json +36 -0
- package/{src → projects/bayan-core-ui/src}/lib/shared/menu.service.ts +1 -1
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/about-dialog-widget/about-dialog-widget.component.html +1 -1
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/about-dialog-widget/about-dialog-widget.component.ts +4 -4
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/change-password-widget/change-password-widget.component.ts +1 -1
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/global-search-widget/global-search-widget.component.ts +9 -10
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/item-widget/item-widget.component.html +2 -2
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/item-widget/item-widget.component.ts +8 -23
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/notifications-widget/notifications-widget.component.html +1 -1
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/notifications-widget/notifications-widget.component.ts +3 -3
- package/projects/bayan-core-ui/src/lib/top-menu-widget/components/settings-widget/settings-widget.component.html +111 -0
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/settings-widget/settings-widget.component.ts +7 -5
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/user-panel-widget/user-panel-widget.component.html +2 -1
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/user-panel-widget/user-panel-widget.component.ts +1 -1
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/top-menu-widget.component.html +6 -2
- package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/top-menu-widget.component.ts +21 -5
- package/projects/bayan-core-ui/src/lib/top-menu-widget/top-menu-widget.styles.css +1378 -0
- package/projects/bayan-core-ui/src/public-api.ts +14 -0
- package/tsconfig.json +40 -0
- package/src/lib/top-menu-widget/components/settings-widget/settings-widget.component.html +0 -119
- package/src/lib/top-menu-widget/top-menu-widget.styles.css +0 -576
- package/src/public-api.ts +0 -7
- /package/{ng-package.json → projects/bayan-core-ui/ng-package.json} +0 -0
- /package/{src → projects/bayan-core-ui/src}/assets/i18n/ar.json +0 -0
- /package/{src → projects/bayan-core-ui/src}/assets/i18n/en.json +0 -0
- /package/{src → projects/bayan-core-ui/src}/assets/i18n/fr.json +0 -0
- /package/{src → projects/bayan-core-ui/src}/lib/shared/common-methods/navigation.utils.ts +0 -0
- /package/{src → projects/bayan-core-ui/src}/lib/shared/menu.dtos.ts +0 -0
- /package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/change-password-widget/change-password-widget.component.html +0 -0
- /package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/components/global-search-widget/global-search-widget.component.html +0 -0
- /package/{src → projects/bayan-core-ui/src}/lib/top-menu-widget/top-menu-widget.models.ts +0 -0
- /package/{tsconfig.lib.json → projects/bayan-core-ui/tsconfig.lib.json} +0 -0
- /package/{tsconfig.lib.prod.json → projects/bayan-core-ui/tsconfig.lib.prod.json} +0 -0
- /package/{tsconfig.spec.json → projects/bayan-core-ui/tsconfig.spec.json} +0 -0
package/.editorconfig
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Editor configuration, see https://editorconfig.org
|
|
2
|
+
root = true
|
|
3
|
+
|
|
4
|
+
[*]
|
|
5
|
+
charset = utf-8
|
|
6
|
+
indent_style = space
|
|
7
|
+
indent_size = 2
|
|
8
|
+
insert_final_newline = true
|
|
9
|
+
trim_trailing_whitespace = true
|
|
10
|
+
|
|
11
|
+
[*.ts]
|
|
12
|
+
quote_type = single
|
|
13
|
+
ij_typescript_use_double_quotes = false
|
|
14
|
+
|
|
15
|
+
[*.md]
|
|
16
|
+
max_line_length = off
|
|
17
|
+
trim_trailing_whitespace = false
|
|
@@ -0,0 +1,632 @@
|
|
|
1
|
+
# Bayan Core Widgets – Widget Development Guide
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
- [Project Overview](#project-overview)
|
|
6
|
+
- [Required Packages & Dependencies](#required-packages--dependencies)
|
|
7
|
+
- [Widget Project Structure](#widget-project-structure)
|
|
8
|
+
- [Widget Standards & Rules](#widget-standards--rules)
|
|
9
|
+
- [Sample Widget: Full Functionality](#sample-widget-full-functionality)
|
|
10
|
+
- [Input & Output Guidelines](#input--output-guidelines)
|
|
11
|
+
- [Translation & Pipes](#translation--pipes)
|
|
12
|
+
- [API Calls](#api-calls)
|
|
13
|
+
- [Naming Standards](#naming-standards)
|
|
14
|
+
- [Versioning Standards](#versioning-standards)
|
|
15
|
+
- [Code Style & Best Practices](#code-style--best-practices)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Project Overview
|
|
20
|
+
|
|
21
|
+
This repository provides reusable, standalone Angular widgets for Bayan products.
|
|
22
|
+
|
|
23
|
+
Use a generic library project naming convention for guidance:
|
|
24
|
+
|
|
25
|
+
`projects/namespace-ui/`
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Required Packages & Dependencies
|
|
30
|
+
|
|
31
|
+
- `@skysoftware-co/bayan-components-ui`
|
|
32
|
+
Provides shared UI components (e.g., Employee Badge).
|
|
33
|
+
- `@skysoftware-co/sky-components-ui`
|
|
34
|
+
Provides additional UI elements (e.g., cards, dividers).
|
|
35
|
+
- `@fortawesome/pro-light-svg-icons`
|
|
36
|
+
For icon support.
|
|
37
|
+
- `@skysoftware-co/bayan-hr-widgets-ui`
|
|
38
|
+
The main widgets package.
|
|
39
|
+
|
|
40
|
+
**Install via npm:**
|
|
41
|
+
npm install @skysoftware-co/bayan-hr-widgets-ui
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Widget Project Structure
|
|
47
|
+
|
|
48
|
+
Each widget should be a standalone Angular component, placed under:
|
|
49
|
+
|
|
50
|
+
`projects/namespace-ui/src/lib/<widget-name>/`
|
|
51
|
+
|
|
52
|
+
Example:
|
|
53
|
+
`projects/namespace-ui/src/lib/top-menu-widget/`
|
|
54
|
+
|
|
55
|
+
Shared reusable DTOs and services used by more than one widget must be placed under:
|
|
56
|
+
|
|
57
|
+
`projects/namespace-ui/src/lib/shared/`
|
|
58
|
+
|
|
59
|
+
Examples:
|
|
60
|
+
`projects/namespace-ui/src/lib/shared/menu.dtos.ts`
|
|
61
|
+
`projects/namespace-ui/src/lib/shared/menu.service.ts`
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Widget Standards & Rules
|
|
66
|
+
|
|
67
|
+
- **Standalone Components:**
|
|
68
|
+
Use Angular standalone components for each widget.
|
|
69
|
+
- **Inputs/Outputs:**
|
|
70
|
+
All external data must be passed via `@Input()` properties.
|
|
71
|
+
All events must be emitted via `@Output()` EventEmitters.
|
|
72
|
+
- **API Integration:**
|
|
73
|
+
Reuse an exported service from `@skysoftware-co/sky-components-ui` before creating any new Widgets-local service.
|
|
74
|
+
Create a dedicated Widgets service only when the package does not provide the required behavior.
|
|
75
|
+
Accept `baseUrl` as an input for API endpoints.
|
|
76
|
+
- **Shared Surface Placement:**
|
|
77
|
+
If a DTO or service is reusable across multiple widgets, place it in `projects/namespace-ui/src/lib/shared/` instead of inside a widget folder.
|
|
78
|
+
- **Repo Targeting:**
|
|
79
|
+
If another repository is mentioned as a source example, treat it as reference-only unless the user explicitly asks to edit that repository.
|
|
80
|
+
- **Portal Reference Rule:**
|
|
81
|
+
Copy behavior and contracts from Portal code when needed, but do not copy Portal-specific folder structure into this widgets library.
|
|
82
|
+
- **Blocked Service Names:**
|
|
83
|
+
Never create Widgets-local services named `CookiesService`, `SecureCookieService`, `SecureStorageService`, `LocalStorageService`, `EncryptionService`, `TranslationService`, `SkyScreenService`, or `SkyPDFService` because those must be reused from `@skysoftware-co/sky-components-ui`.
|
|
84
|
+
- **Translation:**
|
|
85
|
+
Reuse the translation service and pipes exported by `@skysoftware-co/sky-components-ui` for all user-facing text instead of creating local equivalents in Widgets.
|
|
86
|
+
- **Styling:**
|
|
87
|
+
Use CSS classes as input properties for customization.
|
|
88
|
+
- **Error Handling:**
|
|
89
|
+
Emit errors via an `errorOccurred` output event.
|
|
90
|
+
- **Loading State:**
|
|
91
|
+
Emit loading state changes via an `isLoadingChanged` output event.
|
|
92
|
+
- **Pipes:**
|
|
93
|
+
Reuse exported pipes from `@skysoftware-co/sky-components-ui` before creating a new pipe in Widgets.
|
|
94
|
+
- **Blocked Pipe Names:**
|
|
95
|
+
Never create Widgets-local pipes named `capitalizefirst`, `highlight`, `safe`, or `translate` because those must be reused from `@skysoftware-co/sky-components-ui`.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
## Widget Documentation Requirements
|
|
102
|
+
|
|
103
|
+
For this repository, documentation must live at the library project level:
|
|
104
|
+
|
|
105
|
+
`projects/namespace-ui/README.md`
|
|
106
|
+
|
|
107
|
+
Do not create widget README files inside `src/`, `src/lib/`, or the widget folder unless the user explicitly requests them.
|
|
108
|
+
|
|
109
|
+
The project-level README must include:
|
|
110
|
+
|
|
111
|
+
1. **Widget Description:**
|
|
112
|
+
A concise summary of the widget’s purpose and functionality.
|
|
113
|
+
|
|
114
|
+
2. **Inputs Table:**
|
|
115
|
+
A table listing all `@Input()` properties, their types, default values, and descriptions.
|
|
116
|
+
|
|
117
|
+
3. **Outputs Table:**
|
|
118
|
+
A table listing all `@Output()` events, their types, and descriptions.
|
|
119
|
+
|
|
120
|
+
4. **Usage Example:**
|
|
121
|
+
A code snippet showing how to use the widget in a template.
|
|
122
|
+
|
|
123
|
+
**Example README.md structure:**
|
|
124
|
+
The project-level README should include the following sections:
|
|
125
|
+
|
|
126
|
+
Widget <Widget Name>
|
|
127
|
+
|
|
128
|
+
1. Widget Description
|
|
129
|
+
• A concise summary of the widget’s purpose and functionality.
|
|
130
|
+
|
|
131
|
+
2. Inputs Table
|
|
132
|
+
• List all @Input() properties.
|
|
133
|
+
• For each input, provide:
|
|
134
|
+
• Name
|
|
135
|
+
• Type
|
|
136
|
+
• Default Value
|
|
137
|
+
• Description
|
|
138
|
+
|
|
139
|
+
3. Outputs Table
|
|
140
|
+
• List all @Output() events.
|
|
141
|
+
• For each output, provide:
|
|
142
|
+
• Name
|
|
143
|
+
• Type
|
|
144
|
+
• Description
|
|
145
|
+
|
|
146
|
+
4. Usage Example
|
|
147
|
+
• Show a code snippet demonstrating how to use the widget in a template.
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
Example README.md Structure
|
|
152
|
+
# <Widget Name> Widget
|
|
153
|
+
|
|
154
|
+
## Description
|
|
155
|
+
|
|
156
|
+
Briefly describe what this widget does and where it is used.
|
|
157
|
+
|
|
158
|
+
## Inputs
|
|
159
|
+
|
|
160
|
+
| Name | Type | Default Value | Description |
|
|
161
|
+
|--------------|---------|--------------|------------------------------------|
|
|
162
|
+
| baseUrl | string | '' | Base URL for API requests. |
|
|
163
|
+
| headerTitle | string | 'Title' | The title displayed in the header. |
|
|
164
|
+
| isEnabled | boolean | true | Enables or disables the widget. |
|
|
165
|
+
|
|
166
|
+
## Outputs
|
|
167
|
+
|
|
168
|
+
| Name | Type | Description |
|
|
169
|
+
|------------------|----------------------|--------------------------------------|
|
|
170
|
+
| isLoadingChanged | EventEmitter<boolean> | Emits when loading state changes. |
|
|
171
|
+
| errorOccurred | EventEmitter<string> | Emits when an error occurs. |
|
|
172
|
+
|
|
173
|
+
## Usage
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
<hr-widget-name> [baseUrl]="baseUrl"
|
|
177
|
+
[headerTitle]="'My Widget'" [isEnabled]="true" (isLoadingChanged)="onLoadingChanged($event)" (errorOccurred)="onError($event)">
|
|
178
|
+
</hr-widget-name>
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
Rules
|
|
183
|
+
• The Inputs and Outputs tables must include all parameters, with their type, default value (for inputs), and a clear description.
|
|
184
|
+
• Use Markdown tables as shown above for clarity and readability.
|
|
185
|
+
• Update the README.md whenever inputs or outputs change.
|
|
186
|
+
• All new widgets must be documented in the project-level README before merging.
|
|
187
|
+
• Use clear, concise language and keep tables up to date.
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
# 📦 Shared Angular Library/Widget Development Guide (Generic)
|
|
194
|
+
|
|
195
|
+
This section defines the **standard rules and structure** for creating shared Angular library projects (widgets/modules) for any business domain (HR, Payroll, Insurance, etc.).
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## 1. Library Project Structure
|
|
200
|
+
|
|
201
|
+
**Standard folder layout:**
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
projects/
|
|
205
|
+
namespace-ui/
|
|
206
|
+
README.md
|
|
207
|
+
src/
|
|
208
|
+
lib/
|
|
209
|
+
shared/
|
|
210
|
+
[feature1]/
|
|
211
|
+
[feature2]/
|
|
212
|
+
assets/
|
|
213
|
+
package.json
|
|
214
|
+
ng-package.json
|
|
215
|
+
tsconfig.*.json
|
|
216
|
+
```
|
|
217
|
+
- Each feature/widget in its own folder under `lib/`
|
|
218
|
+
- Shared DTOs and shared services in `lib/shared/`
|
|
219
|
+
- All assets (images, translations, etc.) in `src/assets/`
|
|
220
|
+
- Project-level `README.md` documents usage, inputs/outputs, and dependencies
|
|
221
|
+
|
|
222
|
+
## 2. Component/Widget Design Rules
|
|
223
|
+
|
|
224
|
+
- Use **Angular standalone components** for all widgets
|
|
225
|
+
- Expose all visual and behavioral options via `@Input` properties
|
|
226
|
+
- Use `@Output` for all events
|
|
227
|
+
- **Never hardcode styles**: use `[class]` bindings and allow override via `@Input`
|
|
228
|
+
- Default to **Bootstrap 5** utility classes for layout and spacing
|
|
229
|
+
- Use **FontAwesome** for icons via `@fortawesome/angular-fontawesome`
|
|
230
|
+
- All user-facing text must be localizable (see below)
|
|
231
|
+
|
|
232
|
+
## 3. Localization & Lexicon
|
|
233
|
+
|
|
234
|
+
- All user-facing text must:
|
|
235
|
+
- Be passed through a translation pipe (e.g., `{{ 'LabelKey' | translate }}`)
|
|
236
|
+
- Or be exposed as an `@Input` for override
|
|
237
|
+
- Use a shared lexicon/service for all keys; never hardcode literal text
|
|
238
|
+
- Add new label keys to the lexicon and document them in the library README
|
|
239
|
+
|
|
240
|
+
## 4. Dependencies & References
|
|
241
|
+
|
|
242
|
+
- **Always import:**
|
|
243
|
+
- `@skysoftware-co/[core-ui]` for shared UI elements (badges, icons, alerts, etc.)
|
|
244
|
+
- `@ngx-translate/core` for translation support
|
|
245
|
+
- `@fortawesome/angular-fontawesome` for icons
|
|
246
|
+
- **Bootstrap 5** for layout and utility classes
|
|
247
|
+
- List all peer dependencies in `package.json`
|
|
248
|
+
|
|
249
|
+
## 5. Styling
|
|
250
|
+
|
|
251
|
+
- All styles must be class-based and overridable via `@Input`
|
|
252
|
+
- No inline or hardcoded styles in templates
|
|
253
|
+
- Use Bootstrap and custom classes for all layout/appearance
|
|
254
|
+
|
|
255
|
+
## 6. Documentation
|
|
256
|
+
|
|
257
|
+
- Document all `@Input` and `@Output` properties in the library/feature README
|
|
258
|
+
- List all required dependencies and peer dependencies
|
|
259
|
+
- Provide usage examples with translation and style override
|
|
260
|
+
- Document all label keys and their purpose
|
|
261
|
+
|
|
262
|
+
## 7. Reusable Patterns
|
|
263
|
+
|
|
264
|
+
- Use a constants service for all default values that may need override
|
|
265
|
+
- Define all widget data types in a shared `types` folder
|
|
266
|
+
- Use a shared translation pipe for all localization
|
|
267
|
+
|
|
268
|
+
## 8. Checklist for New Shared Libraries
|
|
269
|
+
|
|
270
|
+
- [ ] Use standalone Angular components
|
|
271
|
+
- [ ] All styles via `[class]` and `@Input` properties
|
|
272
|
+
- [ ] All text via translation pipe or `@Input`
|
|
273
|
+
- [ ] Use SkySoftware, Bootstrap, FontAwesome as described
|
|
274
|
+
- [ ] Expose all events via `@Output`
|
|
275
|
+
- [ ] Document all inputs/outputs and usage
|
|
276
|
+
- [ ] Add all label keys to system lexicon
|
|
277
|
+
- [ ] README includes structure, usage, and dependency info
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## 9. Data Flow, Events, and API Integration in Widgets
|
|
282
|
+
|
|
283
|
+
### Inputs: Passing Data from Parent to Widget
|
|
284
|
+
- Every widget **must define `@Input` properties** for all data and configuration needed from the parent.
|
|
285
|
+
- Use strongly typed `@Input` properties for all data models, configuration, and visual options.
|
|
286
|
+
- Document each `@Input` in the widget README, including type, default, and description.
|
|
287
|
+
- Example:
|
|
288
|
+
```typescript
|
|
289
|
+
@Input() employee: EmployeeModel | null = null;
|
|
290
|
+
@Input() baseUrl: string = '';
|
|
291
|
+
@Input() customLabels: Record<string, string> = {};
|
|
292
|
+
```
|
|
293
|
+
- **Best Practice:** Use `@Input` for all data, not service injection, to maximize reusability and testability.
|
|
294
|
+
|
|
295
|
+
### Outputs: Emitting Events for Parent Customization
|
|
296
|
+
- Use `@Output` EventEmitter for all user actions or important state changes inside the widget.
|
|
297
|
+
- Document each `@Output` in the widget README, including event type and when it fires.
|
|
298
|
+
- Example:
|
|
299
|
+
```typescript
|
|
300
|
+
@Output() actionClicked = new EventEmitter<ActionType>();
|
|
301
|
+
@Output() dataChanged = new EventEmitter<WidgetData>();
|
|
302
|
+
```
|
|
303
|
+
- **Pattern:**
|
|
304
|
+
- Fire an event on any button click, selection, or internal action that may require parent handling.
|
|
305
|
+
- Allow parent to subscribe and override or extend widget behavior.
|
|
306
|
+
- **Usage Example:**
|
|
307
|
+
```html
|
|
308
|
+
<my-widget [data]="item" (actionClicked)="onAction($event)"></my-widget>
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Custom Translate Pipe & Lexicon Support
|
|
312
|
+
- Widgets must use a **custom translation pipe** (e.g., `myTranslate`) for all user-facing text.
|
|
313
|
+
- The pipe should:
|
|
314
|
+
- Support multiple languages (en, ar, fr, etc.)
|
|
315
|
+
- Allow injection of a user-defined lexicon (object or service)
|
|
316
|
+
- Fallback to default keys if not found in lexicon
|
|
317
|
+
- **Pattern:**
|
|
318
|
+
```typescript
|
|
319
|
+
@Pipe({ name: 'myTranslate', standalone: true })
|
|
320
|
+
export class MyTranslatePipe implements PipeTransform {
|
|
321
|
+
constructor(private lexiconService: LexiconService) {}
|
|
322
|
+
transform(key: string): string {
|
|
323
|
+
return this.lexiconService.translate(key);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
- **Widget Usage:**
|
|
328
|
+
```html
|
|
329
|
+
<span>{{ 'WidgetTitle' | myTranslate }}</span>
|
|
330
|
+
```
|
|
331
|
+
- **Parent can provide lexicon via service or `@Input` for full customization.**
|
|
332
|
+
|
|
333
|
+
### API Calls and baseUrl Pattern
|
|
334
|
+
- If a widget needs to call an API, always expose a `@Input() baseUrl: string` property.
|
|
335
|
+
- All internal HTTP calls must use this `baseUrl` as the root for endpoints.
|
|
336
|
+
- **Do not hardcode URLs**; always build from `baseUrl` + relative path.
|
|
337
|
+
- Example:
|
|
338
|
+
```typescript
|
|
339
|
+
@Input() baseUrl: string = '';
|
|
340
|
+
// ...
|
|
341
|
+
this.http.get(`${this.baseUrl}/widget/data`)
|
|
342
|
+
```
|
|
343
|
+
- **Best Practice:**
|
|
344
|
+
- Document all API endpoints used by the widget in the README.
|
|
345
|
+
- Allow parent to override `baseUrl` for different environments or backends.
|
|
346
|
+
|
|
347
|
+
---
|
|
348
|
+
|
|
349
|
+
## 10. Referencing Widget Packages in Angular Projects
|
|
350
|
+
|
|
351
|
+
To use a shared widget library (such as HR widgets, Timekeeping widgets, etc.) in your Angular project:
|
|
352
|
+
|
|
353
|
+
### 2. Import the Widget Module/Component
|
|
354
|
+
- For standalone components, import directly in your feature/component:
|
|
355
|
+
```typescript
|
|
356
|
+
import { HrMyMainDetailsWidgetComponent } from '@skysoftware-co/bayan-hr-widgets-ui';
|
|
357
|
+
import { TimekeepingWidgetComponent } from '@skysoftware-co/bayan-timekeeping-widgets-ui';
|
|
358
|
+
```
|
|
359
|
+
- Add to the `imports` array of your standalone component:
|
|
360
|
+
```typescript
|
|
361
|
+
@Component({
|
|
362
|
+
standalone: true,
|
|
363
|
+
imports: [HrMyMainDetailsWidgetComponent, ...],
|
|
364
|
+
// ...
|
|
365
|
+
})
|
|
366
|
+
export class MyFeatureComponent {}
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
### 3. Use the Widget in Your Template
|
|
370
|
+
- Example:
|
|
371
|
+
```html
|
|
372
|
+
<hr-my-main-details-widget [employee]="employeeData" (actionClicked)="onAction($event)"></hr-my-main-details-widget>
|
|
373
|
+
<timekeeping-widget [baseUrl]="apiUrl"></timekeeping-widget>
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### 4. Peer Dependencies
|
|
377
|
+
- Ensure your project has all required peer dependencies (Angular, Bootstrap, FontAwesome, ngx-translate, etc.)
|
|
378
|
+
- See the widget package README for details.
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
**Tip:** Always check the widget package documentation for specific usage, available inputs/outputs, and required setup steps.
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
**Summary:**
|
|
387
|
+
- All widgets must use `@Input` for data/config, `@Output` for events, a custom translate pipe for localization, and `baseUrl` for API calls. This ensures maximum reusability, testability, and external customization.
|
|
388
|
+
|
|
389
|
+
---
|
|
390
|
+
|
|
391
|
+
**This standard applies to all shared Angular library projects in Bayan. Use this as a reference for any new library/module creation.**
|
|
392
|
+
|
|
393
|
+
# i18n JSON File Policy
|
|
394
|
+
- All translation files in assets/i18n/ (en.json, ar.json, fr.json) must use a flat key-value structure (dot notation), e.g.:
|
|
395
|
+
```json
|
|
396
|
+
{
|
|
397
|
+
"APP.TITLE": "...",
|
|
398
|
+
"APP.WELCOME": "..."
|
|
399
|
+
}
|
|
400
|
+
```
|
|
401
|
+
- Nested objects are forbidden in translation files.
|
|
402
|
+
- All documentation, code, and translation usage must follow this flat key policy.
|
|
403
|
+
# Widgets Project Creation Standards
|
|
404
|
+
|
|
405
|
+
## 1. Localization & Internationalization
|
|
406
|
+
- Every widget must support localization using ngx-translate or a compatible translation service.
|
|
407
|
+
- The assets/i18n folder must include at least en.json, ar.json, and fr.json.
|
|
408
|
+
- All display text must use translation keys; never hardcode strings in templates or code.
|
|
409
|
+
- Widgets must accept a lexicon/dictionary input (object of key/value pairs) to override or extend translations at runtime.
|
|
410
|
+
- The lexicon should be merged with system translations, allowing dynamic dictionary updates.
|
|
411
|
+
|
|
412
|
+
## 2. Widget Inputs & Outputs
|
|
413
|
+
- All widgets must expose configuration via strongly typed `@Input()` properties.
|
|
414
|
+
- All outputs/events must use `@Output()` and be clearly documented.
|
|
415
|
+
- Inputs and outputs must be listed in the README and in the public API.
|
|
416
|
+
- Inputs should allow for customization of appearance, data, and behavior.
|
|
417
|
+
|
|
418
|
+
## 3. Lexicon/Dictionary Usage
|
|
419
|
+
- The system lexicon (dictionary of key/value pairs) must be used as the primary source for translation overrides.
|
|
420
|
+
- Widgets should check the lexicon for a key before falling back to the default translation.
|
|
421
|
+
- Lexicon structure example:
|
|
422
|
+
```typescript
|
|
423
|
+
lexicon = { 'WIDGET.TITLE': 'Custom Title', 'WIDGET.BUTTON': 'Go' };
|
|
424
|
+
```
|
|
425
|
+
- Provide a clear API for passing the lexicon to widgets.
|
|
426
|
+
|
|
427
|
+
## 4. Theming, Styling, and Bootstrap Usage
|
|
428
|
+
- Always use the portal's theme library and Bootstrap 5 utility classes before introducing any new custom CSS.
|
|
429
|
+
- Custom classes must only be added if Bootstrap 5 and theme classes cannot achieve the required design.
|
|
430
|
+
- All custom styles must be placed in the assets/Styles/ folder, never inline or in per-component files for shared logic.
|
|
431
|
+
- Support RTL and LTR directions and theme switching if required.
|
|
432
|
+
|
|
433
|
+
## 5. Required Files and Logic
|
|
434
|
+
- Each widget must include:
|
|
435
|
+
- Standalone Angular component (with OnPush change detection)
|
|
436
|
+
- Strongly typed input/output
|
|
437
|
+
- Localization support (translation keys, lexicon input)
|
|
438
|
+
- Theming support (theme and Bootstrap classes)
|
|
439
|
+
- Unit tests
|
|
440
|
+
- Documentation (README)
|
|
441
|
+
- The library must include:
|
|
442
|
+
- i18n folder with at least 3 languages
|
|
443
|
+
- Styles folder for shared/custom styles
|
|
444
|
+
- public-api.ts exporting all widgets/services
|
|
445
|
+
- Constants/configuration service
|
|
446
|
+
- Example usage in README
|
|
447
|
+
|
|
448
|
+
## Widgets Library Project Rules & Policies (HR Widgets Reference)
|
|
449
|
+
|
|
450
|
+
### 1. Project Structure & Standards
|
|
451
|
+
- Use Angular CLI to scaffold the library (Angular 19+).
|
|
452
|
+
- Place all widgets under `projects/[library-name]/src/lib/`.
|
|
453
|
+
- Each widget must be in its own folder, with a standalone component.
|
|
454
|
+
- Shared services, types, and assets must be organized under `lib/services/`, `lib/shared/`, and `src/assets/`.
|
|
455
|
+
- Use a public API file (`public-api.ts`) to export all widgets and services.
|
|
456
|
+
|
|
457
|
+
### 2. Internationalization & Localization
|
|
458
|
+
- Widgets must support multiple languages (en, ar, fr) by reusing the translation service exported from `@skysoftware-co/sky-components-ui`.
|
|
459
|
+
- Reuse translation pipes exported from `@skysoftware-co/sky-components-ui` and do not create duplicate translation pipes in the Widgets project unless no shared option exists.
|
|
460
|
+
- All user-facing text must use translation keys, never hardcoded strings.
|
|
461
|
+
- Allow lexicon overrides for custom translations.
|
|
462
|
+
|
|
463
|
+
### 3. Theming & Styling
|
|
464
|
+
- All style classes must be customizable via input properties.
|
|
465
|
+
- Use CSS classes for all visual customization; never use inline styles.
|
|
466
|
+
- Support dark/light themes and RTL/LTR direction if required by the host portal.
|
|
467
|
+
|
|
468
|
+
### 4. Inputs & Outputs
|
|
469
|
+
- All widget inputs must be strongly typed and documented.
|
|
470
|
+
- Use Angular’s `@Input()` and `@Output()` for configuration and events.
|
|
471
|
+
- Document all input properties and output events in the README.
|
|
472
|
+
|
|
473
|
+
### 5. Dependency Management
|
|
474
|
+
- List all required peer dependencies in package.json (e.g., @skysoftware-co/bayan-components-ui).
|
|
475
|
+
- Use a .npmrc file for private registry access and never commit sensitive tokens.
|
|
476
|
+
|
|
477
|
+
### 6. Build & Publish
|
|
478
|
+
- Use Angular CLI build commands (`ng build [project]`) for building.
|
|
479
|
+
- Publish only the dist output (never source files) using `npm publish`.
|
|
480
|
+
- Ensure the package is versioned and changelog is updated for each release.
|
|
481
|
+
|
|
482
|
+
### 7. Testing
|
|
483
|
+
- Write unit tests for all widgets using Jasmine/Karma.
|
|
484
|
+
- Ensure 100% test coverage for public APIs.
|
|
485
|
+
|
|
486
|
+
### 8. Documentation
|
|
487
|
+
- Provide a detailed README with usage, setup, and input/output documentation.
|
|
488
|
+
- Include setup steps for translation, theming, and peer dependencies.
|
|
489
|
+
|
|
490
|
+
### 9. Constants & Configuration
|
|
491
|
+
- Expose a constants service for default values (e.g., HrConstantsService).
|
|
492
|
+
- Allow runtime overrides for all constants.
|
|
493
|
+
|
|
494
|
+
### 10. Forbidden Patterns
|
|
495
|
+
- No direct API calls inside widgets; all data must come from inputs or services.
|
|
496
|
+
- No hardcoded text, styles, or colors.
|
|
497
|
+
- No global state; widgets must be stateless or use provided services only.
|
|
498
|
+
|
|
499
|
+
|
|
500
|
+
---
|
|
501
|
+
|
|
502
|
+
## Sample Widget: Full Functionality
|
|
503
|
+
|
|
504
|
+
**Component Example:**
|
|
505
|
+
import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
|
|
506
|
+
import { SharedTranslatePipe, SharedWidgetDataService } from '@skysoftware-co/sky-components-ui';
|
|
507
|
+
|
|
508
|
+
@Component({
|
|
509
|
+
selector: 'hr-my-sample-widget',
|
|
510
|
+
standalone: true,
|
|
511
|
+
imports: [SharedTranslatePipe],
|
|
512
|
+
templateUrl: './my-sample-widget.component.html' })
|
|
513
|
+
|
|
514
|
+
export class MySampleWidgetComponent implements OnInit {
|
|
515
|
+
@Input({ required: true }) baseUrl: string = '';
|
|
516
|
+
@Input() someInput: string = '';
|
|
517
|
+
@Output() isLoadingChanged = new EventEmitter<boolean>();
|
|
518
|
+
@Output() errorOccurred = new EventEmitter<string>();
|
|
519
|
+
|
|
520
|
+
constructor(private readonly widgetDataService: SharedWidgetDataService) {
|
|
521
|
+
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
ngOnInit(): void {
|
|
525
|
+
this.isLoadingChanged.emit(true);
|
|
526
|
+
this.widgetDataService.getData(this.baseUrl) .subscribe({
|
|
527
|
+
next: data => {
|
|
528
|
+
/* handle data */ this.isLoadingChanged.emit(false); },
|
|
529
|
+
error: err => {
|
|
530
|
+
this.errorOccurred.emit(err); this.isLoadingChanged.emit(false);
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
} }
|
|
534
|
+
|
|
535
|
+
|
|
536
|
+
**Translation Example:**
|
|
537
|
+
<span>{{ 'MyWidgetTitle' | hrTranslate }}</span>
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
**Pipe Example:**
|
|
541
|
+
<span>{{ value | myCustomPipe }}</span>
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## Input & Output Guidelines
|
|
546
|
+
|
|
547
|
+
- **Inputs:**
|
|
548
|
+
Use `@Input()` for all configurable properties (e.g., `baseUrl`, CSS classes, labels).
|
|
549
|
+
- **Outputs:**
|
|
550
|
+
Use `@Output()` for all events (e.g., `isLoadingChanged`, `errorOccurred`, custom events).
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## Translation & Pipes
|
|
555
|
+
|
|
556
|
+
- **Translation:**
|
|
557
|
+
- Inject and configure the shared translation service exported by `@skysoftware-co/sky-components-ui` in your app.
|
|
558
|
+
- Use the shared translation pipe exported by `@skysoftware-co/sky-components-ui` for all static and dynamic text.
|
|
559
|
+
- **Pipes:**
|
|
560
|
+
- Reuse formatting, filtering, and translation pipes from `@skysoftware-co/sky-components-ui` before creating a new pipe in Widgets.
|
|
561
|
+
|
|
562
|
+
---
|
|
563
|
+
|
|
564
|
+
## API Calls
|
|
565
|
+
|
|
566
|
+
- **Service Layer:**
|
|
567
|
+
- Reuse an exported shared service from `@skysoftware-co/sky-components-ui` when it already covers the widget need.
|
|
568
|
+
- Create a dedicated Widgets service only when the shared package does not provide the required API abstraction.
|
|
569
|
+
- Accept `baseUrl` as an input and append endpoint paths as needed.
|
|
570
|
+
- **Versioning:**
|
|
571
|
+
- Pass `api-version` header as required (e.g., `api-version: 2`).
|
|
572
|
+
|
|
573
|
+
**Example:**
|
|
574
|
+
this.http.get(${this.baseUrl}/hr/widgets/my-widget, {
|
|
575
|
+
headers: { 'api-version': '2' } })
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
## Naming Standards
|
|
581
|
+
|
|
582
|
+
- **Project/Package:**
|
|
583
|
+
- Use kebab-case for npm packages: `@skysoftware-co/bayan-hr-widgets-ui`
|
|
584
|
+
- **Component:**
|
|
585
|
+
- Prefix with `hr-`, use kebab-case: `hr-my-sample-widget`
|
|
586
|
+
- **Class/Service:**
|
|
587
|
+
- Use PascalCase: `MySampleWidgetComponent`, `MySampleWidgetService`
|
|
588
|
+
- **Inputs/Outputs:**
|
|
589
|
+
- Use camelCase: `baseUrl`, `isLoadingChanged`
|
|
590
|
+
|
|
591
|
+
---
|
|
592
|
+
|
|
593
|
+
## Versioning Standards
|
|
594
|
+
|
|
595
|
+
- **NPM Package:**
|
|
596
|
+
- Use [SemVer](https://semver.org/): `MAJOR.MINOR.PATCH`
|
|
597
|
+
- **API Calls:**
|
|
598
|
+
- Use `api-version` header or query parameter for versioning.
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
## Code Style & Best Practices
|
|
603
|
+
|
|
604
|
+
- **Follow Angular and TypeScript best practices.**
|
|
605
|
+
- **Use strong typing for all inputs, outputs, and service responses.**
|
|
606
|
+
- **Document all public APIs and inputs/outputs in JSDoc or markdown.**
|
|
607
|
+
- **Keep widgets focused and reusable.**
|
|
608
|
+
- **Emit loading and error states for all async operations.**
|
|
609
|
+
- **Use dependency injection for services.**
|
|
610
|
+
- **Avoid hardcoding strings; use translation keys.**
|
|
611
|
+
|
|
612
|
+
---
|
|
613
|
+
|
|
614
|
+
## Example: Creating a New Widget
|
|
615
|
+
|
|
616
|
+
1. **Generate Component:**
|
|
617
|
+
ng generate component my-sample-widget --project shared-ui --standalone
|
|
618
|
+
|
|
619
|
+
|
|
620
|
+
2. **Create Service:**
|
|
621
|
+
ng generate service services/my-sample-widget --project shared-ui
|
|
622
|
+
|
|
623
|
+
|
|
624
|
+
3. **Implement Inputs/Outputs, Translation, API Calls, and Error Handling as shown above.**
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
**For more details, refer to the existing widgets in `projects/shared-ui/src/lib/` and the main [README.md](./README.md).**
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
**End of Guide**
|