@posiwise/shared-components 0.0.158 → 0.0.160

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.
@@ -9,7 +9,7 @@ import { NavigationEnd, RouterModule } from '@angular/router';
9
9
  import * as i1$3 from '@posiwise/app-loader';
10
10
  import { AppLoaderModule } from '@posiwise/app-loader';
11
11
  import { CoreTranslocoModule } from '@posiwise/core-transloco';
12
- import * as i3 from '@posiwise/directives';
12
+ import * as i3$1 from '@posiwise/directives';
13
13
  import { DirectivesModule } from '@posiwise/directives';
14
14
  import { PipesModule } from '@posiwise/pipes';
15
15
  import * as i4$2 from '@posiwise/utils';
@@ -31,23 +31,24 @@ import * as i6 from 'primeng/table';
31
31
  import { TableModule } from 'primeng/table';
32
32
  import * as i2$3 from 'primeng/tabs';
33
33
  import { TabsModule } from 'primeng/tabs';
34
- import * as i3$1 from '@ng-bootstrap/ng-bootstrap';
34
+ import * as i3$2 from '@ng-bootstrap/ng-bootstrap';
35
35
  import { NgbTooltipModule, NgbNavModule, NgbModalModule } from '@ng-bootstrap/ng-bootstrap';
36
36
  import { AppBaseComponent } from '@posiwise/app-base-component';
37
37
  import * as i1 from '@posiwise/common-services';
38
38
  import { PermissionService } from '@posiwise/common-services';
39
39
  import { Subject, BehaviorSubject } from 'rxjs';
40
- import { takeUntil, map as map$1, distinctUntilChanged } from 'rxjs/operators';
40
+ import { map, filter, take, takeUntil, distinctUntilChanged } from 'rxjs/operators';
41
+ import * as i3 from '@ngrx/store';
41
42
  import { HelperService } from '@posiwise/helper-service';
42
43
  import * as i4 from '@jsverse/transloco';
43
44
  import { TAG_ENTITY } from '@posiwise/common-utilities';
44
45
  import * as i7$1 from 'primeng/api';
45
46
  import { __decorate, __metadata } from 'tslib';
46
47
  import swal from 'sweetalert2';
47
- import * as i3$2 from 'primeng/tooltip';
48
+ import * as i3$3 from 'primeng/tooltip';
48
49
  import { TooltipModule } from 'primeng/tooltip';
49
50
  import { StatusCodes } from 'http-status-codes';
50
- import map from 'lodash/map';
51
+ import map$1 from 'lodash/map';
51
52
  import * as i2$2 from '@angular/platform-browser';
52
53
  import * as i1$1 from '@posiwise/admin-module-utils';
53
54
  import { DragDropModule } from '@angular/cdk/drag-drop';
@@ -92,31 +93,193 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
92
93
  args: [{ selector: 'pw-authenticator', standalone: false, template: "<!--Auth Page Starts-->\n<section>\n <div class=\"container-fluid\">\n <div class=\"row full-height-vh\">\n <div class=\"col-12 d-flex align-items-center justify-content-center\">\n <h2>Logging...</h2>\n </div>\n </div>\n </div>\n</section>\n<!--Auth Page Ends-->\n" }]
93
94
  }], ctorParameters: () => [{ type: i1.AuthService }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }] });
94
95
 
96
+ function diffRowsFrom(diff) {
97
+ if (!diff) {
98
+ return [];
99
+ }
100
+ return Object.keys(diff).map(field => ({
101
+ field,
102
+ before: formatDiffValue(diff[field].before),
103
+ after: formatDiffValue(diff[field].after)
104
+ }));
105
+ }
106
+ function formatDiffValue(value) {
107
+ if (value === null || value === undefined) {
108
+ return '∅';
109
+ }
110
+ if (typeof value === 'string') {
111
+ return value;
112
+ }
113
+ return JSON.stringify(value);
114
+ }
115
+
116
+ /**
117
+ * Per-user localStorage persistence for the PosiWise Brain chat panel.
118
+ *
119
+ * Why per-user keys: a shared browser session would leak history from
120
+ * user A to user B if keys were global. The pre-ticket #4167 code used
121
+ * a single global `pw-brain.conversation_id` key; this file owns both
122
+ * the new per-user shape AND a one-time migration from the legacy key.
123
+ *
124
+ * Why strip `pending`: server-side confirmation tokens are TTL-bound.
125
+ * Replaying a stale token after hydrate produces a 4xx. Cleaner UX:
126
+ * drop the inline-approve card on reload; the user re-asks if still
127
+ * wanted.
128
+ */
129
+ const STORAGE_PREFIX = 'pw-brain.';
130
+ const LEGACY_CONVERSATION_KEY = 'pw-brain.conversation_id';
131
+ const MAX_STORED_MESSAGES = 100;
132
+ function messagesKeyFor(userId) {
133
+ return userId ? `${STORAGE_PREFIX}messages.${userId}` : `${STORAGE_PREFIX}messages.anonymous`;
134
+ }
135
+ function conversationKeyFor(userId) {
136
+ return userId
137
+ ? `${STORAGE_PREFIX}conversation_id.${userId}`
138
+ : `${STORAGE_PREFIX}conversation_id.anonymous`;
139
+ }
140
+ function serializeMessages(messages) {
141
+ const stripped = messages
142
+ .slice(-MAX_STORED_MESSAGES)
143
+ .map(m => ({ role: m.role, text: m.text }));
144
+ const payload = { v: 1, messages: stripped };
145
+ return JSON.stringify(payload);
146
+ }
147
+ function hydrateMessages(raw) {
148
+ if (!raw) {
149
+ return [];
150
+ }
151
+ try {
152
+ const parsed = JSON.parse(raw);
153
+ if (parsed?.v !== 1 || !Array.isArray(parsed.messages)) {
154
+ return [];
155
+ }
156
+ return parsed.messages
157
+ .filter(m => !!m &&
158
+ (m.role === 'user' || m.role === 'assistant') &&
159
+ typeof m.text === 'string')
160
+ .slice(-MAX_STORED_MESSAGES);
161
+ }
162
+ catch {
163
+ return [];
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Thin coordinator that pairs the `LocalStorage` wrapper with the
169
+ * current user's `api_user_id`. Owns the per-user keys and the one-time
170
+ * migration from the legacy global `pw-brain.conversation_id` slot.
171
+ */
172
+ class BrainChatPersistence {
173
+ constructor(localStorage, userId) {
174
+ this.localStorage = localStorage;
175
+ this.userId = userId;
176
+ }
177
+ readMessages() {
178
+ try {
179
+ return hydrateMessages(this.localStorage.getItem(messagesKeyFor(this.userId)));
180
+ }
181
+ catch {
182
+ return [];
183
+ }
184
+ }
185
+ persistMessages(messages) {
186
+ try {
187
+ this.localStorage
188
+ .setItem$(messagesKeyFor(this.userId), serializeMessages(messages))
189
+ .subscribe();
190
+ }
191
+ catch {
192
+ // private browsing / quota exhausted — best-effort, never break the chat
193
+ }
194
+ }
195
+ /**
196
+ * Read the per-user conversation_id. If absent but the legacy global
197
+ * key still exists (pre-ticket #4167), adopt it into the user-scoped
198
+ * slot and clear the global so the next user on this browser doesn't
199
+ * inherit it.
200
+ */
201
+ adoptConversationId() {
202
+ const scoped = conversationKeyFor(this.userId);
203
+ const existing = this.localStorage.getItem(scoped);
204
+ if (existing) {
205
+ return existing;
206
+ }
207
+ const legacy = this.localStorage.getItem(LEGACY_CONVERSATION_KEY);
208
+ if (!legacy) {
209
+ return null;
210
+ }
211
+ this.localStorage.setItem$(scoped, legacy).subscribe();
212
+ this.localStorage.removeItem$(LEGACY_CONVERSATION_KEY).subscribe();
213
+ return legacy;
214
+ }
215
+ setConversationId(id) {
216
+ this.localStorage.setItem$(conversationKeyFor(this.userId), id).subscribe();
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Open-redirect and pseudo-scheme mitigations for the navigation
222
+ * fall-through branch in pw-brain-chat. Pure functions, extracted from
223
+ * the component for C1 conformance.
224
+ */
225
+ function isAllowedExternalNavigationUrl(url, currentOrigin) {
226
+ if (!(url.startsWith('http://') || url.startsWith('https://'))) {
227
+ return false;
228
+ }
229
+ try {
230
+ return new URL(url).origin === currentOrigin;
231
+ }
232
+ catch {
233
+ return false;
234
+ }
235
+ }
236
+ function isSafeAppRelativePath(path) {
237
+ if (!path.startsWith('/') || path.startsWith('//')) {
238
+ return false;
239
+ }
240
+ const decoded = decodeURIComponent(path);
241
+ return (!decoded.toLowerCase().includes('javascript:') && !decoded.toLowerCase().includes('data:'));
242
+ }
243
+
244
+ const GREETING = 'Hi — I can answer questions about your account and run approved actions. Try “show my API stats”.';
95
245
  class PwBrainChatComponent {
96
- constructor(mcp, router, cdr) {
97
- this.mcp = mcp;
246
+ constructor(orchestrator, localStorage, router, cdr, store) {
247
+ this.orchestrator = orchestrator;
248
+ this.localStorage = localStorage;
98
249
  this.router = router;
99
250
  this.cdr = cdr;
251
+ this.store = store;
100
252
  this.messages = [];
101
253
  this.draft = '';
102
254
  this.loading = false;
103
- this.tools = [];
255
+ this.conversationId = null;
256
+ this.storage = null;
104
257
  this.destroy$ = new Subject();
258
+ this.diffRows = diffRowsFrom;
105
259
  }
106
260
  ngOnInit() {
107
- this.mcp
108
- .listTools()
109
- .pipe(takeUntil(this.destroy$))
110
- .subscribe({
111
- next: res => {
112
- this.tools = res.tools ?? [];
113
- this.pushAssistant(this.buildWelcome());
114
- this.cdr.markForCheck();
115
- },
116
- error: err => {
117
- this.pushAssistant(err?.message ?? 'Could not reach MCP (tools/list).');
118
- this.cdr.markForCheck();
261
+ // Wait for the user to land in the store before hydrating: a bare
262
+ // `take(1)` would race against the initial `currentUser = null`
263
+ // state, switch the storage bucket from `<id>` to `anonymous`, and
264
+ // silently orphan the thread when the user navigates away and back
265
+ // (the second mount would resolve a different bucket — ticket #4167
266
+ // glitch report). `user.id` is the canonical local identifier; it
267
+ // is set once for the lifetime of the session and is present on
268
+ // every authenticated account (unlike `api_user_id`, which only
269
+ // exists when the user has explicitly generated API keys).
270
+ this.store
271
+ .pipe(map(app => app?.user?.currentUser ?? null), filter((user) => !!user && user.id != null), take(1), takeUntil(this.destroy$))
272
+ .subscribe(user => {
273
+ this.storage = new BrainChatPersistence(this.localStorage, String(user.id));
274
+ const hydrated = this.storage.readMessages();
275
+ this.messages = hydrated.length
276
+ ? hydrated.map(m => ({ role: m.role, text: m.text }))
277
+ : [];
278
+ if (!hydrated.length) {
279
+ this.pushAssistant(GREETING);
119
280
  }
281
+ this.conversationId = this.storage.adoptConversationId();
282
+ this.cdr.markForCheck();
120
283
  });
121
284
  }
122
285
  ngOnDestroy() {
@@ -130,109 +293,124 @@ class PwBrainChatComponent {
130
293
  }
131
294
  this.draft = '';
132
295
  this.messages.push({ role: 'user', text });
296
+ this.storage?.persistMessages(this.messages);
133
297
  this.loading = true;
134
298
  this.cdr.markForCheck();
135
- const toolName = this.resolveToolName(text);
136
- if (!toolName) {
137
- this.pushAssistant(this.buildHelpReply());
138
- this.loading = false;
139
- this.cdr.markForCheck();
299
+ this.orchestrator
300
+ .execute({ message: text, conversation_id: this.conversationId ?? undefined })
301
+ .pipe(takeUntil(this.destroy$))
302
+ .subscribe({
303
+ next: response => this.handleExecuteResponse(response),
304
+ error: err => this.handleError(err)
305
+ });
306
+ }
307
+ approve(message) {
308
+ if (!message.pending || this.loading) {
140
309
  return;
141
310
  }
142
- this.mcp
143
- .callTool(toolName, {})
311
+ this.loading = true;
312
+ this.cdr.markForCheck();
313
+ const token = message.pending.confirmation_token;
314
+ // Strip pending state up front so the user can't double-click while
315
+ // the request is in flight; result repopulates the bubble on /confirm.
316
+ message.pending = undefined;
317
+ message.text = 'Approved — running…';
318
+ this.storage?.persistMessages(this.messages);
319
+ this.orchestrator
320
+ .confirm({
321
+ confirmation_token: token,
322
+ conversation_id: this.conversationId ?? undefined
323
+ })
144
324
  .pipe(takeUntil(this.destroy$))
145
325
  .subscribe({
146
- next: result => {
147
- this.applyToolResult(result);
148
- this.loading = false;
149
- this.cdr.markForCheck();
150
- },
151
- error: err => {
152
- this.pushAssistant(err?.message ?? 'MCP tools/call failed.');
153
- this.loading = false;
154
- this.cdr.markForCheck();
155
- }
326
+ next: response => this.handleExecuteResponse(response),
327
+ error: err => this.handleError(err)
156
328
  });
157
329
  }
330
+ cancel(message) {
331
+ message.pending = undefined;
332
+ message.text = 'Cancelled — no action was taken.';
333
+ this.storage?.persistMessages(this.messages);
334
+ this.cdr.markForCheck();
335
+ }
158
336
  trackByIndex(index, _item) {
159
337
  return index;
160
338
  }
161
- buildWelcome() {
162
- if (!this.tools.length) {
163
- return 'No MCP tools are available for your account yet.';
339
+ handleExecuteResponse(response) {
340
+ this.persistConversationId(response.conversation_id);
341
+ if (response.needs_confirmation && response.confirmation_token) {
342
+ this.messages.push({
343
+ role: 'assistant',
344
+ text: response.summary ?? 'Please review and approve this action.',
345
+ pending: {
346
+ confirmation_token: response.confirmation_token,
347
+ risk_level: response.risk_level,
348
+ summary: response.summary,
349
+ target_service: response.target_service,
350
+ target_tool: response.target_tool,
351
+ diff: response.diff
352
+ }
353
+ });
164
354
  }
165
- const list = this.tools.map(t => `${t.name} (${t.description ?? 'no description'})`);
166
- return `Connected to MCP. You can ask about API usage, or say “stats”. Available tools: ${list.join('; ')}.`;
167
- }
168
- buildHelpReply() {
169
- return 'I could not map that to a tool yet. Try: “show my API stats”, “usage”, or “get user stats”.';
170
- }
171
- resolveToolName(text) {
172
- const lower = text.toLowerCase();
173
- if (this.tools.some(t => t.name === 'get_user_stats')) {
174
- if (/\b(stats?|usage|hits?|api|account|quota|get_user_stats)\b/i.test(lower) ||
175
- lower.includes('user stats')) {
176
- return 'get_user_stats';
177
- }
355
+ else if (response.result_status === 'success') {
356
+ this.applySuccessResult(response);
178
357
  }
179
- const byName = this.tools.find(t => lower.includes(t.name) || lower.includes(t.name.replace(/_/g, ' ')));
180
- return byName?.name ?? null;
358
+ else {
359
+ this.pushAssistant(response.reason ?? 'I could not complete that request.');
360
+ }
361
+ this.storage?.persistMessages(this.messages);
362
+ this.loading = false;
363
+ this.cdr.markForCheck();
181
364
  }
182
- applyToolResult(result) {
183
- if (result && typeof result === 'object' && result !== null && 'navigate_to' in result) {
184
- const url = String(result.navigate_to).trim();
185
- if (url.startsWith('http://') || url.startsWith('https://')) {
186
- if (this.isAllowedExternalNavigationUrl(url)) {
187
- this.pushAssistant(`Navigating to: ${url}`);
188
- window.location.assign(url);
189
- }
190
- else {
191
- this.pushAssistant('Navigation was not performed: full URLs must use the same origin as this app.');
192
- }
193
- }
194
- else if (this.isSafeAppRelativePath(url)) {
365
+ applySuccessResult(response) {
366
+ const tool = response.tool_result;
367
+ if (tool && typeof tool.navigate_to === 'string') {
368
+ const url = tool.navigate_to.trim();
369
+ if (isAllowedExternalNavigationUrl(url, window.location.origin)) {
195
370
  this.pushAssistant(`Navigating to: ${url}`);
196
- this.router.navigateByUrl(url).catch(() => {
197
- this.pushAssistant('Navigation failed.');
198
- });
371
+ window.location.assign(url);
372
+ return;
199
373
  }
200
- else {
201
- this.pushAssistant('Navigation was not performed: use a single-root path (e.g. /admin/users), not // or javascript: URLs.');
374
+ if (isSafeAppRelativePath(url)) {
375
+ this.pushAssistant(`Navigating to: ${url}`);
376
+ this.router
377
+ .navigateByUrl(url)
378
+ .catch(() => this.pushAssistant('Navigation failed.'));
379
+ return;
202
380
  }
381
+ this.pushAssistant('Navigation was not performed: use a single-root path (e.g. /admin/users), not //, javascript:, or data: URLs.');
203
382
  return;
204
383
  }
205
- const text = typeof result === 'string' ? result : JSON.stringify(result, null, 2);
206
- this.pushAssistant(text);
384
+ this.pushAssistant(response.response ?? JSON.stringify(response.tool_result ?? {}, null, 2));
207
385
  }
208
- /** Mitigate open redirects: only same-origin absolute URLs. */
209
- isAllowedExternalNavigationUrl(url) {
210
- try {
211
- return new URL(url).origin === window.location.origin;
212
- }
213
- catch {
214
- return false;
386
+ handleError(err) {
387
+ let message = 'PosiWise Brain request failed.';
388
+ if (err && typeof err === 'object') {
389
+ const e = err;
390
+ message = e.error?.detail ?? e.error?.message ?? e.message ?? message;
215
391
  }
392
+ this.pushAssistant(message);
393
+ this.loading = false;
394
+ this.cdr.markForCheck();
216
395
  }
217
- /** Block protocol-relative and pseudo-scheme paths passed to Router. */
218
- isSafeAppRelativePath(path) {
219
- if (!path.startsWith('/') || path.startsWith('//')) {
220
- return false;
396
+ persistConversationId(id) {
397
+ if (!id || id === this.conversationId) {
398
+ return;
221
399
  }
222
- const decoded = decodeURIComponent(path);
223
- return (!decoded.toLowerCase().includes('javascript:') &&
224
- !decoded.toLowerCase().includes('data:'));
400
+ this.conversationId = id;
401
+ this.storage?.setConversationId(id);
225
402
  }
226
403
  pushAssistant(text) {
227
404
  this.messages.push({ role: 'assistant', text });
405
+ this.storage?.persistMessages(this.messages);
228
406
  }
229
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PwBrainChatComponent, deps: [{ token: i1.McpJsonRpcService }, { token: i2.Router }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
230
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: PwBrainChatComponent, isStandalone: false, selector: "pw-brain-chat", ngImport: i0, template: "<div class=\"pw-brain-chat\">\n <div class=\"pw-brain-chat__thread\" role=\"log\" aria-live=\"polite\">\n @for (m of messages; track trackByIndex($index, m)) {\n <div\n class=\"pw-brain-chat__row\"\n [class.pw-brain-chat__row--user]=\"m.role === 'user'\"\n >\n <div class=\"pw-brain-chat__bubble\">\n <pre class=\"pw-brain-chat__text\">{{ m.text }}</pre>\n </div>\n </div>\n }\n </div>\n\n @if (loading) {\n <div class=\"pw-brain-chat__loading\" aria-hidden=\"false\">Working\u2026</div>\n }\n\n <div class=\"pw-brain-chat__compose\">\n <label class=\"visually-hidden\" for=\"pw-brain-chat-input\">Message MCP</label>\n <textarea\n id=\"pw-brain-chat-input\"\n class=\"form-control pw-brain-chat__input\"\n rows=\"2\"\n [(ngModel)]=\"draft\"\n placeholder=\"Ask PosiWise Brain\u2026\"\n (keydown.enter)=\"$event.preventDefault(); send()\"\n ></textarea>\n <button\n type=\"button\"\n class=\"btn btn-primary btn-sm pw-brain-chat__send\"\n [disabled]=\"loading || !draft.trim()\"\n (click)=\"send()\"\n >\n Send\n </button>\n </div>\n</div>\n", styles: [".pw-brain-chat{display:flex;flex-direction:column;height:100%;min-height:0}.pw-brain-chat__thread{flex:1 1 auto;min-height:0;overflow-y:auto;padding:12px 0;display:flex;flex-direction:column;gap:10px}.pw-brain-chat__row{display:flex;justify-content:flex-start}.pw-brain-chat__row--user{justify-content:flex-end}.pw-brain-chat__bubble{max-width:92%;border-radius:10px;padding:8px 12px;background:#eef1f4;border:1px solid rgba(0,0,0,.06)}.pw-brain-chat__row--user .pw-brain-chat__bubble{background:var(--tabs_bg, #0d6efd);border-color:transparent;color:var(--tabs_text, #fff)}.pw-brain-chat__text{margin:0;white-space:pre-wrap;word-break:break-word;font-family:inherit;font-size:13px;line-height:1.45}.pw-brain-chat__loading{font-size:12px;color:#6c757d;padding:4px 0 0}.pw-brain-chat__compose{flex-shrink:0;display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid rgba(0,0,0,.08)}.pw-brain-chat__input{resize:none;font-size:13px}.pw-brain-chat__send{align-self:flex-end}\n"], dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
407
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PwBrainChatComponent, deps: [{ token: i1.MCPOrchestratorService }, { token: i1.LocalStorage }, { token: i2.Router }, { token: i0.ChangeDetectorRef }, { token: i3.Store }], target: i0.ɵɵFactoryTarget.Component }); }
408
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: PwBrainChatComponent, isStandalone: false, selector: "pw-brain-chat", ngImport: i0, template: "<div class=\"pw-brain-chat\">\n <div class=\"pw-brain-chat__thread\" role=\"log\" aria-live=\"polite\">\n @for (m of messages; track trackByIndex($index, m)) {\n <div\n class=\"pw-brain-chat__row\"\n [class.pw-brain-chat__row--user]=\"m.role === 'user'\"\n >\n <div class=\"pw-brain-chat__bubble\">\n <pre class=\"pw-brain-chat__text\">{{ m.text }}</pre>\n @if (m.pending) {\n <div class=\"pw-brain-chat__confirm\" role=\"group\" aria-label=\"Approve action\">\n <div class=\"pw-brain-chat__confirm-meta\">\n @if (m.pending.risk_level) {\n <span\n class=\"pw-brain-chat__risk\"\n [class.pw-brain-chat__risk--critical]=\"m.pending.risk_level === 'critical'\"\n [class.pw-brain-chat__risk--high]=\"m.pending.risk_level === 'high'\"\n [class.pw-brain-chat__risk--medium]=\"m.pending.risk_level === 'medium'\"\n [class.pw-brain-chat__risk--low]=\"m.pending.risk_level === 'low'\"\n >Risk: {{ m.pending.risk_level }}</span>\n }\n @if (m.pending.target_service && m.pending.target_tool) {\n <span class=\"pw-brain-chat__target\"\n >{{ m.pending.target_service }}.{{ m.pending.target_tool }}</span\n >\n }\n </div>\n @if (diffRows(m.pending.diff).length) {\n <table class=\"pw-brain-chat__diff\" aria-label=\"Field-level diff\">\n <thead>\n <tr>\n <th scope=\"col\">Field</th>\n <th scope=\"col\">Before</th>\n <th scope=\"col\">After</th>\n </tr>\n </thead>\n <tbody>\n @for (row of diffRows(m.pending.diff); track row.field) {\n <tr>\n <th scope=\"row\" class=\"pw-brain-chat__diff-field\">{{ row.field }}</th>\n <td class=\"pw-brain-chat__diff-before\">{{ row.before }}</td>\n <td class=\"pw-brain-chat__diff-after\">{{ row.after }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n <div class=\"pw-brain-chat__confirm-actions\">\n <button\n type=\"button\"\n class=\"btn btn-success btn-sm pw-brain-chat__approve\"\n [disabled]=\"loading\"\n (click)=\"approve(m)\"\n >Approve</button>\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary btn-sm pw-brain-chat__cancel\"\n [disabled]=\"loading\"\n (click)=\"cancel(m)\"\n >Cancel</button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (loading) {\n <div class=\"pw-brain-chat__loading\" aria-hidden=\"false\">Working\u2026</div>\n }\n\n <div class=\"pw-brain-chat__compose\">\n <label class=\"visually-hidden\" for=\"pw-brain-chat-input\">Message MCP</label>\n <textarea\n id=\"pw-brain-chat-input\"\n class=\"form-control pw-brain-chat__input\"\n rows=\"2\"\n [(ngModel)]=\"draft\"\n placeholder=\"Ask PosiWise Brain\u2026\"\n (keydown.enter)=\"$event.preventDefault(); send()\"\n ></textarea>\n <button\n type=\"button\"\n class=\"btn btn-primary btn-sm pw-brain-chat__send\"\n [disabled]=\"loading || !draft.trim()\"\n (click)=\"send()\"\n >\n Send\n </button>\n </div>\n</div>\n", styles: [".pw-brain-chat{display:flex;flex-direction:column;height:100%;min-height:0}.pw-brain-chat__thread{flex:1 1 auto;min-height:0;overflow-y:auto;padding:12px 0;display:flex;flex-direction:column;gap:10px}.pw-brain-chat__row{display:flex;justify-content:flex-start}.pw-brain-chat__row--user{justify-content:flex-end}.pw-brain-chat__bubble{max-width:92%;border-radius:10px;padding:8px 12px;background:#eef1f4;border:1px solid rgba(0,0,0,.06)}.pw-brain-chat__row--user .pw-brain-chat__bubble{background:var(--tabs_bg, #0d6efd);border-color:transparent;color:var(--tabs_text, #fff)}.pw-brain-chat__text{margin:0;white-space:pre-wrap;word-break:break-word;font-family:inherit;font-size:13px;line-height:1.45}.pw-brain-chat__loading{font-size:12px;color:#6c757d;padding:4px 0 0}.pw-brain-chat__compose{flex-shrink:0;display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid rgba(0,0,0,.08)}.pw-brain-chat__input{resize:none;font-size:13px}.pw-brain-chat__send{align-self:flex-end}.pw-brain-chat__confirm{margin-top:8px;padding:8px;border-radius:8px;background:#ffc10714;border:1px solid rgba(255,193,7,.45);display:flex;flex-direction:column;gap:8px}.pw-brain-chat__confirm-meta{display:flex;flex-wrap:wrap;gap:8px;font-size:12px;color:#6c757d}.pw-brain-chat__risk{text-transform:uppercase;font-weight:600;padding:1px 6px;border-radius:3px;background:#0000000d}.pw-brain-chat__risk--critical{background:#dc354526;color:#842029}.pw-brain-chat__risk--high{background:#fd7e1426;color:#8a4d10}.pw-brain-chat__risk--medium{background:#ffc10733;color:#6c5400}.pw-brain-chat__risk--low{background:#19875426;color:#0f5132}.pw-brain-chat__target{font-family:monospace;font-size:11px;color:#495057}.pw-brain-chat__confirm-actions{display:flex;gap:8px}\n"], dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
231
409
  }
232
410
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PwBrainChatComponent, decorators: [{
233
411
  type: Component,
234
- args: [{ selector: 'pw-brain-chat', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div class=\"pw-brain-chat\">\n <div class=\"pw-brain-chat__thread\" role=\"log\" aria-live=\"polite\">\n @for (m of messages; track trackByIndex($index, m)) {\n <div\n class=\"pw-brain-chat__row\"\n [class.pw-brain-chat__row--user]=\"m.role === 'user'\"\n >\n <div class=\"pw-brain-chat__bubble\">\n <pre class=\"pw-brain-chat__text\">{{ m.text }}</pre>\n </div>\n </div>\n }\n </div>\n\n @if (loading) {\n <div class=\"pw-brain-chat__loading\" aria-hidden=\"false\">Working\u2026</div>\n }\n\n <div class=\"pw-brain-chat__compose\">\n <label class=\"visually-hidden\" for=\"pw-brain-chat-input\">Message MCP</label>\n <textarea\n id=\"pw-brain-chat-input\"\n class=\"form-control pw-brain-chat__input\"\n rows=\"2\"\n [(ngModel)]=\"draft\"\n placeholder=\"Ask PosiWise Brain\u2026\"\n (keydown.enter)=\"$event.preventDefault(); send()\"\n ></textarea>\n <button\n type=\"button\"\n class=\"btn btn-primary btn-sm pw-brain-chat__send\"\n [disabled]=\"loading || !draft.trim()\"\n (click)=\"send()\"\n >\n Send\n </button>\n </div>\n</div>\n", styles: [".pw-brain-chat{display:flex;flex-direction:column;height:100%;min-height:0}.pw-brain-chat__thread{flex:1 1 auto;min-height:0;overflow-y:auto;padding:12px 0;display:flex;flex-direction:column;gap:10px}.pw-brain-chat__row{display:flex;justify-content:flex-start}.pw-brain-chat__row--user{justify-content:flex-end}.pw-brain-chat__bubble{max-width:92%;border-radius:10px;padding:8px 12px;background:#eef1f4;border:1px solid rgba(0,0,0,.06)}.pw-brain-chat__row--user .pw-brain-chat__bubble{background:var(--tabs_bg, #0d6efd);border-color:transparent;color:var(--tabs_text, #fff)}.pw-brain-chat__text{margin:0;white-space:pre-wrap;word-break:break-word;font-family:inherit;font-size:13px;line-height:1.45}.pw-brain-chat__loading{font-size:12px;color:#6c757d;padding:4px 0 0}.pw-brain-chat__compose{flex-shrink:0;display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid rgba(0,0,0,.08)}.pw-brain-chat__input{resize:none;font-size:13px}.pw-brain-chat__send{align-self:flex-end}\n"] }]
235
- }], ctorParameters: () => [{ type: i1.McpJsonRpcService }, { type: i2.Router }, { type: i0.ChangeDetectorRef }] });
412
+ args: [{ selector: 'pw-brain-chat', changeDetection: ChangeDetectionStrategy.OnPush, standalone: false, template: "<div class=\"pw-brain-chat\">\n <div class=\"pw-brain-chat__thread\" role=\"log\" aria-live=\"polite\">\n @for (m of messages; track trackByIndex($index, m)) {\n <div\n class=\"pw-brain-chat__row\"\n [class.pw-brain-chat__row--user]=\"m.role === 'user'\"\n >\n <div class=\"pw-brain-chat__bubble\">\n <pre class=\"pw-brain-chat__text\">{{ m.text }}</pre>\n @if (m.pending) {\n <div class=\"pw-brain-chat__confirm\" role=\"group\" aria-label=\"Approve action\">\n <div class=\"pw-brain-chat__confirm-meta\">\n @if (m.pending.risk_level) {\n <span\n class=\"pw-brain-chat__risk\"\n [class.pw-brain-chat__risk--critical]=\"m.pending.risk_level === 'critical'\"\n [class.pw-brain-chat__risk--high]=\"m.pending.risk_level === 'high'\"\n [class.pw-brain-chat__risk--medium]=\"m.pending.risk_level === 'medium'\"\n [class.pw-brain-chat__risk--low]=\"m.pending.risk_level === 'low'\"\n >Risk: {{ m.pending.risk_level }}</span>\n }\n @if (m.pending.target_service && m.pending.target_tool) {\n <span class=\"pw-brain-chat__target\"\n >{{ m.pending.target_service }}.{{ m.pending.target_tool }}</span\n >\n }\n </div>\n @if (diffRows(m.pending.diff).length) {\n <table class=\"pw-brain-chat__diff\" aria-label=\"Field-level diff\">\n <thead>\n <tr>\n <th scope=\"col\">Field</th>\n <th scope=\"col\">Before</th>\n <th scope=\"col\">After</th>\n </tr>\n </thead>\n <tbody>\n @for (row of diffRows(m.pending.diff); track row.field) {\n <tr>\n <th scope=\"row\" class=\"pw-brain-chat__diff-field\">{{ row.field }}</th>\n <td class=\"pw-brain-chat__diff-before\">{{ row.before }}</td>\n <td class=\"pw-brain-chat__diff-after\">{{ row.after }}</td>\n </tr>\n }\n </tbody>\n </table>\n }\n <div class=\"pw-brain-chat__confirm-actions\">\n <button\n type=\"button\"\n class=\"btn btn-success btn-sm pw-brain-chat__approve\"\n [disabled]=\"loading\"\n (click)=\"approve(m)\"\n >Approve</button>\n <button\n type=\"button\"\n class=\"btn btn-outline-secondary btn-sm pw-brain-chat__cancel\"\n [disabled]=\"loading\"\n (click)=\"cancel(m)\"\n >Cancel</button>\n </div>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n @if (loading) {\n <div class=\"pw-brain-chat__loading\" aria-hidden=\"false\">Working\u2026</div>\n }\n\n <div class=\"pw-brain-chat__compose\">\n <label class=\"visually-hidden\" for=\"pw-brain-chat-input\">Message MCP</label>\n <textarea\n id=\"pw-brain-chat-input\"\n class=\"form-control pw-brain-chat__input\"\n rows=\"2\"\n [(ngModel)]=\"draft\"\n placeholder=\"Ask PosiWise Brain\u2026\"\n (keydown.enter)=\"$event.preventDefault(); send()\"\n ></textarea>\n <button\n type=\"button\"\n class=\"btn btn-primary btn-sm pw-brain-chat__send\"\n [disabled]=\"loading || !draft.trim()\"\n (click)=\"send()\"\n >\n Send\n </button>\n </div>\n</div>\n", styles: [".pw-brain-chat{display:flex;flex-direction:column;height:100%;min-height:0}.pw-brain-chat__thread{flex:1 1 auto;min-height:0;overflow-y:auto;padding:12px 0;display:flex;flex-direction:column;gap:10px}.pw-brain-chat__row{display:flex;justify-content:flex-start}.pw-brain-chat__row--user{justify-content:flex-end}.pw-brain-chat__bubble{max-width:92%;border-radius:10px;padding:8px 12px;background:#eef1f4;border:1px solid rgba(0,0,0,.06)}.pw-brain-chat__row--user .pw-brain-chat__bubble{background:var(--tabs_bg, #0d6efd);border-color:transparent;color:var(--tabs_text, #fff)}.pw-brain-chat__text{margin:0;white-space:pre-wrap;word-break:break-word;font-family:inherit;font-size:13px;line-height:1.45}.pw-brain-chat__loading{font-size:12px;color:#6c757d;padding:4px 0 0}.pw-brain-chat__compose{flex-shrink:0;display:flex;flex-direction:column;gap:8px;padding-top:10px;border-top:1px solid rgba(0,0,0,.08)}.pw-brain-chat__input{resize:none;font-size:13px}.pw-brain-chat__send{align-self:flex-end}.pw-brain-chat__confirm{margin-top:8px;padding:8px;border-radius:8px;background:#ffc10714;border:1px solid rgba(255,193,7,.45);display:flex;flex-direction:column;gap:8px}.pw-brain-chat__confirm-meta{display:flex;flex-wrap:wrap;gap:8px;font-size:12px;color:#6c757d}.pw-brain-chat__risk{text-transform:uppercase;font-weight:600;padding:1px 6px;border-radius:3px;background:#0000000d}.pw-brain-chat__risk--critical{background:#dc354526;color:#842029}.pw-brain-chat__risk--high{background:#fd7e1426;color:#8a4d10}.pw-brain-chat__risk--medium{background:#ffc10733;color:#6c5400}.pw-brain-chat__risk--low{background:#19875426;color:#0f5132}.pw-brain-chat__target{font-family:monospace;font-size:11px;color:#495057}.pw-brain-chat__confirm-actions{display:flex;gap:8px}\n"] }]
413
+ }], ctorParameters: () => [{ type: i1.MCPOrchestratorService }, { type: i1.LocalStorage }, { type: i2.Router }, { type: i0.ChangeDetectorRef }, { type: i3.Store }] });
236
414
 
237
415
  class ClearBitIconComponent {
238
416
  constructor() {
@@ -251,7 +429,7 @@ class ClearBitIconComponent {
251
429
  }
252
430
  }
253
431
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: ClearBitIconComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
254
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: ClearBitIconComponent, isStandalone: false, selector: "pw-clearbit-icon", inputs: { src: "src", altText: "altText", dummyPath: "dummyPath" }, usesOnChanges: true, ngImport: i0, template: "<img [src]=\"clearBitSrc\"\n [alt]=\"altText\"\n class=\"img-fluid company-logo me-2 mt-1\" />\n", styles: [".company-logo{height:25px;width:25px}\n"], dependencies: [{ kind: "directive", type: i3.LazyImgDirective, selector: "img" }] }); }
432
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: ClearBitIconComponent, isStandalone: false, selector: "pw-clearbit-icon", inputs: { src: "src", altText: "altText", dummyPath: "dummyPath" }, usesOnChanges: true, ngImport: i0, template: "<img [src]=\"clearBitSrc\"\n [alt]=\"altText\"\n class=\"img-fluid company-logo me-2 mt-1\" />\n", styles: [".company-logo{height:25px;width:25px}\n"], dependencies: [{ kind: "directive", type: i3$1.LazyImgDirective, selector: "img" }] }); }
255
433
  }
256
434
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: ClearBitIconComponent, decorators: [{
257
435
  type: Component,
@@ -406,6 +584,22 @@ class CollapsibleSidebarComponent {
406
584
  this.destroy$ = new Subject();
407
585
  }
408
586
  ngOnInit() {
587
+ // Self-register the PosiWise Brain (MCP) panel so every consumer
588
+ // frontend (main-frontend, cloudolive-frontend, products-frontend,
589
+ // angular-frontend-template) behaves identically just by rendering
590
+ // <pw-collapsible-sidebar> — no per-app dashboard-layout wiring. The
591
+ // shared @posiwise/core-components navbar emits the trigger
592
+ // (pwCollapsibleSidebarTrigger [contentId]="'posiwise-brain'") in all
593
+ // of them; without this registration `loadContent()` silently bails
594
+ // and the widget never opens. `registerContent` is idempotent (Map
595
+ // keyed by id), so remount / multiple hosts are safe. The slot is
596
+ // intentionally NOT unregistered on destroy (ticket #4167: sticky
597
+ // BehaviorSubject state across dashboard remount).
598
+ this.sidebarService.registerContent({
599
+ id: 'posiwise-brain',
600
+ title: 'PosiWise Brain',
601
+ component: PwBrainChatComponent
602
+ });
409
603
  // Subscribe to expanded state
410
604
  this.sidebarService.sidebarExpanded$
411
605
  .pipe(takeUntil(this.destroy$))
@@ -413,7 +607,20 @@ class CollapsibleSidebarComponent {
413
607
  this.isExpanded = isExpanded;
414
608
  this.cdr.markForCheck();
415
609
  });
416
- // Subscribe to content changes
610
+ }
611
+ ngAfterViewInit() {
612
+ // `sidebarContent$` is a BehaviorSubject — it emits its current value
613
+ // SYNCHRONOUSLY on subscribe. If we subscribed in ngOnInit, the
614
+ // first emission would arrive before `contentContainer` (a
615
+ // @ViewChild) is bound, and `loadComponent()` would silently bail
616
+ // out with `Content container not found`. That used to be benign
617
+ // because `unregisterContent` nulled the slot on dashboard destroy
618
+ // (so the first emission was null), but ticket #4167's
619
+ // open-on-navigate-back fix keeps the slot populated — without
620
+ // moving the subscription here, the new sidebar instance receives
621
+ // the existing content reference too early and never mounts the
622
+ // chat. Subscribe AFTER the view is initialised so the first
623
+ // emission lands with `contentContainer` already wired up.
417
624
  this.sidebarService.sidebarContent$.pipe(takeUntil(this.destroy$)).subscribe(content => {
418
625
  this.currentContent = content;
419
626
  if (content) {
@@ -424,8 +631,6 @@ class CollapsibleSidebarComponent {
424
631
  }
425
632
  this.cdr.markForCheck();
426
633
  });
427
- }
428
- ngAfterViewInit() {
429
634
  // Double rAF: wait until after layout so we do not trigger transitions from mount → closed.
430
635
  requestAnimationFrame(() => {
431
636
  requestAnimationFrame(() => {
@@ -610,7 +815,7 @@ class HeaderComponent extends AppBaseComponent {
610
815
  this.isMenuCollapsed = !this.isMenuCollapsed;
611
816
  }
612
817
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HeaderComponent, deps: [{ token: i0.Injector }, { token: i1.AuthService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
613
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HeaderComponent, isStandalone: false, selector: "pw-header", inputs: { landing: "landing" }, usesInheritance: true, ngImport: i0, template: "<div class=\"navbar navbar-expand-lg fixed-top-nav fixed-top\"\n [ngClass]=\"{ 'navbar-blue': !landing }\">\n <div class=\"container d-block\">\n <div class=\"row m-0\">\n <div class=\"col-lg-2 float-start\">\n <a href=\"/\">\n <img [src]=\"logo\"\n class=\"header-logo\"\n alt=\"site-logo\" />\n </a>\n <button type=\"button\"\n class=\"navbar-toggle\"\n (click)=\"toggleMenu()\"\n [attr.aria-expanded]=\"!isMenuCollapsed\">\n <span class=\"icon-bar\"></span> <span class=\"icon-bar\"></span>\n <span class=\"icon-bar\"></span>\n </button>\n </div>\n <div class=\"col-lg-10 nav-outer mt-2\">\n <div class=\"navbar-collapse float-end\"\n [class.collapse]=\"isMenuCollapsed\"\n [class.show]=\"!isMenuCollapsed\"\n id=\"myNavbar\">\n <nav class=\"navbar navbar-expand-sm bg-light\">\n <ul class=\"navbar-nav\">\n <li class=\"nav-item contact-button\">\n <a href=\"/\"\n class=\"\">{{ 'Button.Home' | transloco }}</a>\n </li>\n @if (!loggedIn) {\n <li class=\"nav-item login-button\">\n <a class=\"\"\n (click)=\"navigateToLogin()\"> log in</a>\n </li>\n }\n </ul>\n </nav>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.navbar-blue{background-color:var(--first);box-shadow:2px 2px 15px 2px #0000001f;transition:width 2s,height 2s,transform 2s background-color .5s ease;z-index:9999}.fixed-top-nav{display:block!important;height:60px}.navbar-toggle{display:none}.navbar-toggle .icon-bar{color:#fff}.nav-outer{text-align:right}.nav-outer nav{background:none!important;display:inline-block;float:none;width:auto}.nav-outer li a{color:#fff;font-size:18px;margin:0 0 0 30px;text-transform:capitalize}.nav-outer li a:hover{color:#fff;text-decoration:none}.nav-outer li a:focus{color:#fff}.navbar-nav li{display:inline-block}@media screen and (max-width:1199px){.nav-outer li a{margin:0 10px}}@media screen and (max-width:991px){.icon-bar{background-color:#fff;border-radius:1px;display:block;height:2px;margin-top:4px;width:22px}.navbar-toggle{background-color:#ffb92b!important;background-image:none;border:1px solid rgb(255,255,255);border-radius:4px;display:block!important;float:right;margin-top:4px;padding:9px 10px;position:relative}.collapse{display:none!important}.collapse.show{display:block!important}.nav-outer nav{background:#ffb92b!important;display:inline-block;float:left;padding:20px;width:100%}.nav-outer li a{margin:0;padding:0}.navbar-expand-sm,.navbar-nav{-webkit-box-direction:normal;-webkit-box-orient:horizontal;flex-direction:column}li.nav-item{float:left;margin-bottom:12px;text-align:left;width:100%}.navbar-expand-sm{-webkit-box-direction:normal;-webkit-box-orient:horizontal;-webkit-box-pack:start;flex-flow:column nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{left:auto;right:0}.nav-outer li a:hover{color:#0a56d3}.contact-button a,.login-button a,.nav-item{background:none;color:#fff!important;font-weight:600}.contact-button a:hover,.login-button a:hover,.nav-item a:hover{color:#0a56d3!important}}@media screen and (max-width:767px){.fixed-top{padding:10px;top:0!important}}@media screen and (max-width:575px){.fixed-top{padding:10px;top:0!important}}@media screen and (max-width:375px){.navbar .container{padding:0!important}}@media(min-width:641px)and (max-width:991px){.navbar-toggle{margin-top:6px}}.header-logo{height:auto!important;width:auto;max-height:40px;max-width:100%;object-fit:contain}.login-button a{background-color:var(--second);color:#fff}.login-button a:hover{background-color:#fff;color:var(--second)!important}.contact-button a{background-color:var(--third);color:#fff}.contact-button a:hover{background-color:#fff;color:var(--third)!important}.fixed-top{position:fixed!important}\n"], dependencies: [{ kind: "directive", type: i3.LazyImgDirective, selector: "img" }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
818
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HeaderComponent, isStandalone: false, selector: "pw-header", inputs: { landing: "landing" }, usesInheritance: true, ngImport: i0, template: "<div class=\"navbar navbar-expand-lg fixed-top-nav fixed-top\"\n [ngClass]=\"{ 'navbar-blue': !landing }\">\n <div class=\"container d-block\">\n <div class=\"row m-0\">\n <div class=\"col-lg-2 float-start\">\n <a href=\"/\">\n <img [src]=\"logo\"\n class=\"header-logo\"\n alt=\"site-logo\" />\n </a>\n <button type=\"button\"\n class=\"navbar-toggle\"\n (click)=\"toggleMenu()\"\n [attr.aria-expanded]=\"!isMenuCollapsed\">\n <span class=\"icon-bar\"></span> <span class=\"icon-bar\"></span>\n <span class=\"icon-bar\"></span>\n </button>\n </div>\n <div class=\"col-lg-10 nav-outer mt-2\">\n <div class=\"navbar-collapse float-end\"\n [class.collapse]=\"isMenuCollapsed\"\n [class.show]=\"!isMenuCollapsed\"\n id=\"myNavbar\">\n <nav class=\"navbar navbar-expand-sm bg-light\">\n <ul class=\"navbar-nav\">\n <li class=\"nav-item contact-button\">\n <a href=\"/\"\n class=\"\">{{ 'Button.Home' | transloco }}</a>\n </li>\n @if (!loggedIn) {\n <li class=\"nav-item login-button\">\n <a class=\"\"\n (click)=\"navigateToLogin()\"> log in</a>\n </li>\n }\n </ul>\n </nav>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.navbar-blue{background-color:var(--first);box-shadow:2px 2px 15px 2px #0000001f;transition:width 2s,height 2s,transform 2s background-color .5s ease;z-index:9999}.fixed-top-nav{display:block!important;height:60px}.navbar-toggle{display:none}.navbar-toggle .icon-bar{color:#fff}.nav-outer{text-align:right}.nav-outer nav{background:none!important;display:inline-block;float:none;width:auto}.nav-outer li a{color:#fff;font-size:18px;margin:0 0 0 30px;text-transform:capitalize}.nav-outer li a:hover{color:#fff;text-decoration:none}.nav-outer li a:focus{color:#fff}.navbar-nav li{display:inline-block}@media screen and (max-width:1199px){.nav-outer li a{margin:0 10px}}@media screen and (max-width:991px){.icon-bar{background-color:#fff;border-radius:1px;display:block;height:2px;margin-top:4px;width:22px}.navbar-toggle{background-color:#ffb92b!important;background-image:none;border:1px solid rgb(255,255,255);border-radius:4px;display:block!important;float:right;margin-top:4px;padding:9px 10px;position:relative}.collapse{display:none!important}.collapse.show{display:block!important}.nav-outer nav{background:#ffb92b!important;display:inline-block;float:left;padding:20px;width:100%}.nav-outer li a{margin:0;padding:0}.navbar-expand-sm,.navbar-nav{-webkit-box-direction:normal;-webkit-box-orient:horizontal;flex-direction:column}li.nav-item{float:left;margin-bottom:12px;text-align:left;width:100%}.navbar-expand-sm{-webkit-box-direction:normal;-webkit-box-orient:horizontal;-webkit-box-pack:start;flex-flow:column nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{left:auto;right:0}.nav-outer li a:hover{color:#0a56d3}.contact-button a,.login-button a,.nav-item{background:none;color:#fff!important;font-weight:600}.contact-button a:hover,.login-button a:hover,.nav-item a:hover{color:#0a56d3!important}}@media screen and (max-width:767px){.fixed-top{padding:10px;top:0!important}}@media screen and (max-width:575px){.fixed-top{padding:10px;top:0!important}}@media screen and (max-width:375px){.navbar .container{padding:0!important}}@media(min-width:641px)and (max-width:991px){.navbar-toggle{margin-top:6px}}.header-logo{height:auto!important;width:auto;max-height:40px;max-width:100%;object-fit:contain}.login-button a{background-color:var(--second);color:#fff}.login-button a:hover{background-color:#fff;color:var(--second)!important}.contact-button a{background-color:var(--third);color:#fff}.contact-button a:hover{background-color:#fff;color:var(--third)!important}.fixed-top{position:fixed!important}\n"], dependencies: [{ kind: "directive", type: i3$1.LazyImgDirective, selector: "img" }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
614
819
  }
615
820
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HeaderComponent, decorators: [{
616
821
  type: Component,
@@ -655,7 +860,7 @@ class NoDataComponent {
655
860
  }
656
861
  <ng-content></ng-content>
657
862
  </div>
658
- `, isInline: true, styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.no-data{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%;border:1px dashed rgb(204,204,204);border-radius:4px;margin:20px 0;padding:10px;background:#fafafa!important;color:oklch(from var(--text) 40% c h)!important}.no-data .message{font-weight:600;font-size:15px;color:oklch(from var(--text) 40% c h)!important}.no-data.has-content{padding-top:10px;padding-bottom:20px}.no-data .nothing-found-image{margin-top:15px;height:auto;max-width:150px}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.LazyImgDirective, selector: "img" }] }); }
863
+ `, isInline: true, styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.no-data{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%;border:1px dashed rgb(204,204,204);border-radius:4px;margin:20px 0;padding:10px;background:#fafafa!important;color:oklch(from var(--text) 40% c h)!important}.no-data .message{font-weight:600;font-size:15px;color:oklch(from var(--text) 40% c h)!important}.no-data.has-content{padding-top:10px;padding-bottom:20px}.no-data .nothing-found-image{margin-top:15px;height:auto;max-width:150px}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.LazyImgDirective, selector: "img" }] }); }
659
864
  }
660
865
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: NoDataComponent, decorators: [{
661
866
  type: Component,
@@ -829,13 +1034,13 @@ class EntityGroupComponent extends AppBaseComponent {
829
1034
  ngOnDestroy() {
830
1035
  super.ngOnDestroy();
831
1036
  }
832
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EntityGroupComponent, deps: [{ token: i1.GroupService }, { token: i1.SubscriptionService }, { token: i3$1.NgbModal }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
833
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: EntityGroupComponent, isStandalone: false, selector: "pw-entity-group", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Team View</h2>\n\n <p>\n In this section, based on your permissions, you can add/remove members from your\n teams.\n <br />\n Then, you'll be able to see powerful insight on the activities performed by your\n team's members.\n </p>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 col-xs-12 d-flex align-items-sm-center align-items-top text-start pe-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"ms-sm-2 d-inline mt-0 card-title mb-3 mb-sm-0\">\n Team view: {{ selectedGroup?.name }}\n </h3>\n </div>\n <div class=\"col-md-6 col-xs-12 text-end justify-content-end\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"open()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-2\"\n (click)=\"navigateToCommunications()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> See Communications\n </button>\n }\n </div>\n </div>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n <div class=\"primeng-datatable-container table-responsive\"\n [class.hideTable]=\"subscribedMembers?.length === 0\">\n <p-table #dt\n [value]=\"subscribedMembers\"\n [paginator]=\"true\"\n [rows]=\"PAGE_SIZE\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\">{{ 'Label.FirstName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.LastName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\"\n let-member>\n <tr class=\"table-row\">\n <td data-head=\"First Name\">\n <a [routerLink]=\"['/members', member.slug]\">{{ member.first_name || null }}\n </a>\n </td>\n <td data-head=\"Last Name\">{{ member.last_name || null }}</td>\n <td data-head=\"Email\">{{ member.email }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (member.id !== userId) {\n <li ngbTooltip=\"Message\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"member.slug\">\n <i\n class=\"fa fa-comments cta1-icon\"\n *rbacAllow=\"chatPermission\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n @if (hasAccess) {\n <li ngbTooltip=\"Remove\"\n class=\"me-2 me-sm-3\"\n (click)=\"onDelete(member.id)\"\n (keydown.enter)=\"onDelete(member.id)\"\n (keydown.space)=\"onDelete(member.id)\"\n >\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n @if (subscribedMembers?.length === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"There are no members in this team yet.\"\n >\n </pw-no-data>\n }\n </div>\n\n <ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add Members</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Please start typing to select the members to add to this team.</p>\n <div class=\"ui-fluid skills-modal\">\n <p-autoComplete [suggestions]=\"filteredMembers\"\n [(ngModel)]=\"selectedMembers\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n placeholder=\"Member\"\n [multiple]=\"true\">\n </p-autoComplete>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"closeModal(modal)\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"onSave()\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </ng-template>\n", styles: ["a.previous i{line-height:23px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.RbacAllowDirective, selector: "[rbacAllow]", inputs: ["rbacAllow"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i3$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i6.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i7$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i9.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
1037
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EntityGroupComponent, deps: [{ token: i1.GroupService }, { token: i1.SubscriptionService }, { token: i3$2.NgbModal }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1038
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: EntityGroupComponent, isStandalone: false, selector: "pw-entity-group", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Team View</h2>\n\n <p>\n In this section, based on your permissions, you can add/remove members from your\n teams.\n <br />\n Then, you'll be able to see powerful insight on the activities performed by your\n team's members.\n </p>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 col-xs-12 d-flex align-items-sm-center align-items-top text-start pe-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"ms-sm-2 d-inline mt-0 card-title mb-3 mb-sm-0\">\n Team view: {{ selectedGroup?.name }}\n </h3>\n </div>\n <div class=\"col-md-6 col-xs-12 text-end justify-content-end\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"open()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-2\"\n (click)=\"navigateToCommunications()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> See Communications\n </button>\n }\n </div>\n </div>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n <div class=\"primeng-datatable-container table-responsive\"\n [class.hideTable]=\"subscribedMembers?.length === 0\">\n <p-table #dt\n [value]=\"subscribedMembers\"\n [paginator]=\"true\"\n [rows]=\"PAGE_SIZE\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\">{{ 'Label.FirstName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.LastName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\"\n let-member>\n <tr class=\"table-row\">\n <td data-head=\"First Name\">\n <a [routerLink]=\"['/members', member.slug]\">{{ member.first_name || null }}\n </a>\n </td>\n <td data-head=\"Last Name\">{{ member.last_name || null }}</td>\n <td data-head=\"Email\">{{ member.email }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (member.id !== userId) {\n <li ngbTooltip=\"Message\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"member.slug\">\n <i\n class=\"fa fa-comments cta1-icon\"\n *rbacAllow=\"chatPermission\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n @if (hasAccess) {\n <li ngbTooltip=\"Remove\"\n class=\"me-2 me-sm-3\"\n (click)=\"onDelete(member.id)\"\n (keydown.enter)=\"onDelete(member.id)\"\n (keydown.space)=\"onDelete(member.id)\"\n >\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n @if (subscribedMembers?.length === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"There are no members in this team yet.\"\n >\n </pw-no-data>\n }\n </div>\n\n <ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add Members</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Please start typing to select the members to add to this team.</p>\n <div class=\"ui-fluid skills-modal\">\n <p-autoComplete [suggestions]=\"filteredMembers\"\n [(ngModel)]=\"selectedMembers\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n placeholder=\"Member\"\n [multiple]=\"true\">\n </p-autoComplete>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"closeModal(modal)\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"onSave()\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </ng-template>\n", styles: ["a.previous i{line-height:23px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$1.RbacAllowDirective, selector: "[rbacAllow]", inputs: ["rbacAllow"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i3$2.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i6.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i7$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i9.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
834
1039
  }
835
1040
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EntityGroupComponent, decorators: [{
836
1041
  type: Component,
837
1042
  args: [{ selector: 'pw-entity-group', standalone: false, template: "<div>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Team View</h2>\n\n <p>\n In this section, based on your permissions, you can add/remove members from your\n teams.\n <br />\n Then, you'll be able to see powerful insight on the activities performed by your\n team's members.\n </p>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 col-xs-12 d-flex align-items-sm-center align-items-top text-start pe-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"ms-sm-2 d-inline mt-0 card-title mb-3 mb-sm-0\">\n Team view: {{ selectedGroup?.name }}\n </h3>\n </div>\n <div class=\"col-md-6 col-xs-12 text-end justify-content-end\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"open()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-2\"\n (click)=\"navigateToCommunications()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> See Communications\n </button>\n }\n </div>\n </div>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n <div class=\"primeng-datatable-container table-responsive\"\n [class.hideTable]=\"subscribedMembers?.length === 0\">\n <p-table #dt\n [value]=\"subscribedMembers\"\n [paginator]=\"true\"\n [rows]=\"PAGE_SIZE\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\">{{ 'Label.FirstName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.LastName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\"\n let-member>\n <tr class=\"table-row\">\n <td data-head=\"First Name\">\n <a [routerLink]=\"['/members', member.slug]\">{{ member.first_name || null }}\n </a>\n </td>\n <td data-head=\"Last Name\">{{ member.last_name || null }}</td>\n <td data-head=\"Email\">{{ member.email }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (member.id !== userId) {\n <li ngbTooltip=\"Message\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"member.slug\">\n <i\n class=\"fa fa-comments cta1-icon\"\n *rbacAllow=\"chatPermission\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n @if (hasAccess) {\n <li ngbTooltip=\"Remove\"\n class=\"me-2 me-sm-3\"\n (click)=\"onDelete(member.id)\"\n (keydown.enter)=\"onDelete(member.id)\"\n (keydown.space)=\"onDelete(member.id)\"\n >\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n @if (subscribedMembers?.length === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"There are no members in this team yet.\"\n >\n </pw-no-data>\n }\n </div>\n\n <ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add Members</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Please start typing to select the members to add to this team.</p>\n <div class=\"ui-fluid skills-modal\">\n <p-autoComplete [suggestions]=\"filteredMembers\"\n [(ngModel)]=\"selectedMembers\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n placeholder=\"Member\"\n [multiple]=\"true\">\n </p-autoComplete>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"closeModal(modal)\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"onSave()\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </ng-template>\n", styles: ["a.previous i{line-height:23px}\n"] }]
838
- }], ctorParameters: () => [{ type: i1.GroupService }, { type: i1.SubscriptionService }, { type: i3$1.NgbModal }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
1043
+ }], ctorParameters: () => [{ type: i1.GroupService }, { type: i1.SubscriptionService }, { type: i3$2.NgbModal }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
839
1044
  type: ViewChild,
840
1045
  args: ['content', { static: true }]
841
1046
  }] } });
@@ -1001,7 +1206,7 @@ class GroupDefinitionComponent extends AppBaseComponent {
1001
1206
  super.ngOnDestroy();
1002
1207
  }
1003
1208
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GroupDefinitionComponent, deps: [{ token: i1.GroupService }, { token: i2$1.UntypedFormBuilder }, { token: i1.SubscriptionService }, { token: i1.DataService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1004
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: GroupDefinitionComponent, isStandalone: false, selector: "pw-group-definition", usesInheritance: true, ngImport: i0, template: "<section>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Enterprise Teams Categories</h2>\n\n <p>\n Here you can define the categories for your enterprise's groups. For example \"Sales\n Department\", \"Development Department\", etc.\n <br />\n Once the category created, you'll be able to add teams to them and see useful\n insight based on the members activity in the corresponding team.\n </p>\n </div>\n </div>\n\n @if (!viewDefinition) {\n <div class=\"row\"\n >\n <div class=\"col-6 d-flex align-items-center text-start mb-sm-3 mb-lg-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"previous()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n </div>\n @if (hasAccess) {\n <div class=\"col-6\"\n >\n <button class=\"float-end btn btn-sm btn-outline-primary me-2\"\n (click)=\"viewDefinitions()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Create Team Category\n </button>\n </div>\n }\n </div>\n }\n\n @if (viewDefinition) {\n <div>\n <h4 class=\"card-title d-inline mb-5\">\n {{ viewEdit ? 'Update the' : 'Create a new' }} category\n </h4>\n @if (!viewEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"saveGroupDefinition()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-name-label\" class=\"pw-label-style\">{{ 'Label.Name' | transloco }}</span>\n <input type=\"text\"\n id=\"group-definition-name\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'group-definition-name-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}</span>\n <input type=\"text\"\n id=\"group-definition-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'group-definition-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-is_private-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.IsPrivate' | transloco }}</span>\n <div class=\"display-block\">\n <ui-switch size=\"small\"\n [attr.aria-labelledby]=\"'group-definition-is_private-label'\"\n checkedLabel=\"True\"\n uncheckedLabel=\"false\"\n formControlName=\"is_private\">\n </ui-switch>\n </div>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"categoryBusyButton\"\n class=\"btn btn-primary\">Add Category</button>\n </div>\n </div>\n </form>\n </div>\n }\n @if (viewEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"updateDetails()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-name-label\" class=\"pw-label-style\">{{ 'Label.Name' | transloco }}: </span>\n <input type=\"text\"\n id=\"group-definition-edit-name\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'group-definition-edit-name-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}:</span>\n <input type=\"text\"\n id=\"group-definition-edit-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'group-definition-edit-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-is_private-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.IsPrivate' | transloco }}</span>\n <div class=\"display-block\">\n <ui-switch size=\"small\"\n [attr.aria-labelledby]=\"'group-definition-edit-is_private-label'\"\n checkedLabel=\"True\"\n uncheckedLabel=\"false\"\n formControlName=\"is_private\">\n </ui-switch>\n </div>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"categoryBusyButton\"\n class=\"btn btn-primary\">\n {{ 'Button.Update' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n }\n </div>\n }\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if (groupDefinition?.length !== 0) {\n @if (!viewDefinition) {\n <div class=\"row mb-last-3 group-definitions-wrapper\"\n >\n @for (group of groupDefinition; track group) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3\"\n >\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h5 class=\"mb-3\">{{ group.name }}</h5>\n <p>{{ group.description | slice: 0:200 }}</p>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (hasAccess) {\n <a class=\"btn btn-sm btn-outline-danger me-2\"\n (click)=\"onDelete(group.id)\">{{ 'Button.Delete' | transloco }}</a>\n }\n @if (hasAccess) {\n <a class=\"btn btn-sm btn-outline-primary me-2\"\n (click)=\"onGroupDefinitionEdit(group.id)\">{{ 'Button.Edit' | transloco }}</a>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n }\n @if (groupDefinition?.length === 0 && hasAccess && !viewDefinition && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoLabelsMessage' | transloco\"> </pw-no-data>\n </div>\n }\n @if (groupDefinition?.length === 0 && !hasAccess && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoLabelsUserMessage' | transloco\"> </pw-no-data>\n </div>\n }\n </section>\n", styles: [".mb-last-3{margin-bottom:3rem}\n"], dependencies: [{ kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i5.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i7.SlicePipe, name: "slice" }] }); }
1209
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: GroupDefinitionComponent, isStandalone: false, selector: "pw-group-definition", usesInheritance: true, ngImport: i0, template: "<section>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Enterprise Teams Categories</h2>\n\n <p>\n Here you can define the categories for your enterprise's groups. For example \"Sales\n Department\", \"Development Department\", etc.\n <br />\n Once the category created, you'll be able to add teams to them and see useful\n insight based on the members activity in the corresponding team.\n </p>\n </div>\n </div>\n\n @if (!viewDefinition) {\n <div class=\"row\"\n >\n <div class=\"col-6 d-flex align-items-center text-start mb-sm-3 mb-lg-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"previous()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n </div>\n @if (hasAccess) {\n <div class=\"col-6\"\n >\n <button class=\"float-end btn btn-sm btn-outline-primary me-2\"\n (click)=\"viewDefinitions()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Create Team Category\n </button>\n </div>\n }\n </div>\n }\n\n @if (viewDefinition) {\n <div>\n <h4 class=\"card-title d-inline mb-5\">\n {{ viewEdit ? 'Update the' : 'Create a new' }} category\n </h4>\n @if (!viewEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"saveGroupDefinition()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-name-label\" class=\"pw-label-style\">{{ 'Label.Name' | transloco }}</span>\n <input type=\"text\"\n id=\"group-definition-name\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'group-definition-name-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}</span>\n <input type=\"text\"\n id=\"group-definition-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'group-definition-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-is_private-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.IsPrivate' | transloco }}</span>\n <div class=\"display-block\">\n <ui-switch size=\"small\"\n [attr.aria-labelledby]=\"'group-definition-is_private-label'\"\n checkedLabel=\"True\"\n uncheckedLabel=\"false\"\n formControlName=\"is_private\">\n </ui-switch>\n </div>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"categoryBusyButton\"\n class=\"btn btn-primary\">Add Category</button>\n </div>\n </div>\n </form>\n </div>\n }\n @if (viewEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"updateDetails()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-name-label\" class=\"pw-label-style\">{{ 'Label.Name' | transloco }}: </span>\n <input type=\"text\"\n id=\"group-definition-edit-name\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'group-definition-edit-name-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}:</span>\n <input type=\"text\"\n id=\"group-definition-edit-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'group-definition-edit-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-is_private-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.IsPrivate' | transloco }}</span>\n <div class=\"display-block\">\n <ui-switch size=\"small\"\n [attr.aria-labelledby]=\"'group-definition-edit-is_private-label'\"\n checkedLabel=\"True\"\n uncheckedLabel=\"false\"\n formControlName=\"is_private\">\n </ui-switch>\n </div>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"categoryBusyButton\"\n class=\"btn btn-primary\">\n {{ 'Button.Update' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n }\n </div>\n }\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if (groupDefinition?.length !== 0) {\n @if (!viewDefinition) {\n <div class=\"row mb-last-3 group-definitions-wrapper\"\n >\n @for (group of groupDefinition; track group) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3\"\n >\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h5 class=\"mb-3\">{{ group.name }}</h5>\n <p>{{ group.description | slice: 0:200 }}</p>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (hasAccess) {\n <a class=\"btn btn-sm btn-outline-danger me-2\"\n (click)=\"onDelete(group.id)\">{{ 'Button.Delete' | transloco }}</a>\n }\n @if (hasAccess) {\n <a class=\"btn btn-sm btn-outline-primary me-2\"\n (click)=\"onGroupDefinitionEdit(group.id)\">{{ 'Button.Edit' | transloco }}</a>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n }\n @if (groupDefinition?.length === 0 && hasAccess && !viewDefinition && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoLabelsMessage' | transloco\"> </pw-no-data>\n </div>\n }\n @if (groupDefinition?.length === 0 && !hasAccess && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoLabelsUserMessage' | transloco\"> </pw-no-data>\n </div>\n }\n </section>\n", styles: [".mb-last-3{margin-bottom:3rem}\n"], dependencies: [{ kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3$1.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i5.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i7.SlicePipe, name: "slice" }] }); }
1005
1210
  }
1006
1211
  __decorate([
1007
1212
  ValidateForm('form'),
@@ -1233,7 +1438,7 @@ class GroupsComponent extends AppBaseComponent {
1233
1438
  super.ngOnDestroy();
1234
1439
  }
1235
1440
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GroupsComponent, deps: [{ token: i2$1.UntypedFormBuilder }, { token: i1.GroupService }, { token: i1.SubscriptionService }, { token: i1.DataService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1236
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: GroupsComponent, isStandalone: false, selector: "pw-groups", usesInheritance: true, ngImport: i0, template: "<div>\n <section>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Enterprise Teams</h2>\n\n <p>\n Here you can define the teams for your Enterprise members. For example\n \"Corporate Sales Team\", \"Frontend Dev Team\" etc.\n <br />\n Once the teams created, you'll be able to add members to them and see useful\n insight based on the members activity in the corresponding team.\n </p>\n </div>\n </div>\n\n @if (!isGroupOperations) {\n <div class=\"row\"\n >\n <div class=\"col-12 d-flex justify-content-end align-items-center text-end mb-3\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"groupOperation()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Team\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-1\"\n [routerLink]=\"['/' + subscription?.slug + '/enterprise', 'groups', 'labels']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Manage Team Categories\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Add Group Template -->\n @if (isGroupOperations) {\n <div\n class=\"mb-4\">\n <h4 class=\"card-title d-inline\">{{ viewEdit ? 'Update the' : 'Create a new' }} team</h4>\n @if (!isGroupEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"saveGroup()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-teamName-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamName' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-teamName\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'groups-teamName-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'groups-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-teamCategory-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamCategory' | transloco\n }}<span class=\"text-danger required-icon\">*</span>\n </span>\n <p-select\n [attr.aria-labelledby]=\"'groups-teamCategory-label'\"\n [options]=\"groupDefinition\"\n formControlName=\"group_definition_id\"\n [ngClass]=\"{'is-invalid': submitted && form.controls['group_definition_id'].errors}\"\n [placeholder]=\"'Select Team Category'\"\n optionValue=\"id\"\n optionLabel=\"name\">\n </p-select>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n (click)=\"isGroupOperations = !isGroupOperations\"\n class=\"btn btn-outline-default me-2\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">Add</button>\n </div>\n </div>\n </form>\n </div>\n }\n <!-- Edit Group Template -->\n @if (isGroupEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"updateDetails()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-teamName-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamName' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-edit-teamName\"\n class=\"form-control\"\n formControlName=\"name\"\n required=\"true\"\n [attr.aria-labelledby]=\"'groups-edit-teamName-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamDescription' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-edit-description\"\n value=\"{{ description }}\"\n class=\"form-control\"\n formControlName=\"description\"\n required=\"true\"\n [attr.aria-labelledby]=\"'groups-edit-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-teamCategory-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamCategory' | transloco\n }}<span class=\"text-danger required-icon\">*</span>\n </span>\n <p-select\n [attr.aria-labelledby]=\"'groups-edit-teamCategory-label'\"\n [options]=\"groupDefinition\"\n formControlName=\"group_definition_id\"\n [ngClass]=\"{'is-invalid': submitted && form.controls['group_definition_id'].errors}\"\n [placeholder]=\"'Select Team Category'\"\n optionValue=\"id\"\n optionLabel=\"name\">\n </p-select>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"cancelUpdate()\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">\n {{ 'Button.Update' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n }\n </div>\n }\n\n @if (!isGroupOperations) {\n <div class=\"row\"\n >\n <div class=\"col-4 mt-2 filter\">\n <p-select\n [options]=\"domainGroupDefinition\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [ngModel]=\"'0'\"\n (onChange)=\"filterDomainsList($event.value)\">\n </p-select>\n </div>\n </div>\n }\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (!isGroupOperations) {\n <div class=\"row group_list my-4\"\n >\n @for (group of allGroups; track trackByGroup($index, group)) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3\"\n >\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h5 class=\"mb-3\">{{ group.name }}</h5>\n <p>{{ group.description | slice: 0:200 }}</p>\n <span><a class=\"badge bg-primary\">{{\n group?.group_definition_name\n }}</a></span>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (hasAccess) {\n <a class=\"me-2 my-1\"\n aria-label=\"Delete\"\n (click)=\"onDelete(group.id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i></a>\n }\n @if (hasAccess) {\n <a class=\"me-2 my-1\"\n aria-label=\"Edit Group\"\n (click)=\"editGroup(group.id)\"><i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i></a>\n }\n <a class=\"me-2 my-1\"\n aria-label=\"Members\"\n [routerLink]=\"[group.id, 'members']\"><i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </a>\n <a class=\"communications me-2 my-1\"\n aria-label=\"Communications\"\n (click)=\"navigateToCommunications(group.id)\"><i class=\"fa fa-comments cta2-icon\" aria-hidden=\"true\"></i></a>\n <a class=\"communications my-1\"\n aria-label=\"Documents\"\n (click)=\"navigateToDocumentations(group.id)\"><i class=\"fab fa-wikipedia-w cta1-icon\" aria-hidden=\"true\"></i></a>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </section>\n </div>\n @if (allGroups?.length === 0 && hasAccess && !isGroupOperations && isLoaded) {\n <div\n class=\"clear-both\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoTeamMessage' | transloco\"> </pw-no-data>\n </div>\n }\n @if (allGroups?.length === 0 && !hasAccess && !isGroupOperations && isLoaded) {\n <div\n class=\"clear-both\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoTeamMessageIfUser' | transloco\"> </pw-no-data>\n </div>\n }\n", styles: ["a.previous i{line-height:13px}.clear-both{clear:both}@media screen and (max-width:480px){.filter{flex:none;max-width:100%!important}.communications{margin-top:2%}}\n"], dependencies: [{ kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i5$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i7.SlicePipe, name: "slice" }] }); }
1441
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: GroupsComponent, isStandalone: false, selector: "pw-groups", usesInheritance: true, ngImport: i0, template: "<div>\n <section>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Enterprise Teams</h2>\n\n <p>\n Here you can define the teams for your Enterprise members. For example\n \"Corporate Sales Team\", \"Frontend Dev Team\" etc.\n <br />\n Once the teams created, you'll be able to add members to them and see useful\n insight based on the members activity in the corresponding team.\n </p>\n </div>\n </div>\n\n @if (!isGroupOperations) {\n <div class=\"row\"\n >\n <div class=\"col-12 d-flex justify-content-end align-items-center text-end mb-3\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"groupOperation()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Team\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-1\"\n [routerLink]=\"['/' + subscription?.slug + '/enterprise', 'groups', 'labels']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Manage Team Categories\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Add Group Template -->\n @if (isGroupOperations) {\n <div\n class=\"mb-4\">\n <h4 class=\"card-title d-inline\">{{ viewEdit ? 'Update the' : 'Create a new' }} team</h4>\n @if (!isGroupEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"saveGroup()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-teamName-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamName' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-teamName\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'groups-teamName-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'groups-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-teamCategory-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamCategory' | transloco\n }}<span class=\"text-danger required-icon\">*</span>\n </span>\n <p-select\n [attr.aria-labelledby]=\"'groups-teamCategory-label'\"\n [options]=\"groupDefinition\"\n formControlName=\"group_definition_id\"\n [ngClass]=\"{'is-invalid': submitted && form.controls['group_definition_id'].errors}\"\n [placeholder]=\"'Select Team Category'\"\n optionValue=\"id\"\n optionLabel=\"name\">\n </p-select>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n (click)=\"isGroupOperations = !isGroupOperations\"\n class=\"btn btn-outline-default me-2\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">Add</button>\n </div>\n </div>\n </form>\n </div>\n }\n <!-- Edit Group Template -->\n @if (isGroupEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"updateDetails()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-teamName-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamName' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-edit-teamName\"\n class=\"form-control\"\n formControlName=\"name\"\n required=\"true\"\n [attr.aria-labelledby]=\"'groups-edit-teamName-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamDescription' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-edit-description\"\n value=\"{{ description }}\"\n class=\"form-control\"\n formControlName=\"description\"\n required=\"true\"\n [attr.aria-labelledby]=\"'groups-edit-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-teamCategory-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamCategory' | transloco\n }}<span class=\"text-danger required-icon\">*</span>\n </span>\n <p-select\n [attr.aria-labelledby]=\"'groups-edit-teamCategory-label'\"\n [options]=\"groupDefinition\"\n formControlName=\"group_definition_id\"\n [ngClass]=\"{'is-invalid': submitted && form.controls['group_definition_id'].errors}\"\n [placeholder]=\"'Select Team Category'\"\n optionValue=\"id\"\n optionLabel=\"name\">\n </p-select>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"cancelUpdate()\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">\n {{ 'Button.Update' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n }\n </div>\n }\n\n @if (!isGroupOperations) {\n <div class=\"row\"\n >\n <div class=\"col-4 mt-2 filter\">\n <p-select\n [options]=\"domainGroupDefinition\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [ngModel]=\"'0'\"\n (onChange)=\"filterDomainsList($event.value)\">\n </p-select>\n </div>\n </div>\n }\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (!isGroupOperations) {\n <div class=\"row group_list my-4\"\n >\n @for (group of allGroups; track trackByGroup($index, group)) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3\"\n >\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h5 class=\"mb-3\">{{ group.name }}</h5>\n <p>{{ group.description | slice: 0:200 }}</p>\n <span><a class=\"badge bg-primary\">{{\n group?.group_definition_name\n }}</a></span>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (hasAccess) {\n <a class=\"me-2 my-1\"\n aria-label=\"Delete\"\n (click)=\"onDelete(group.id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i></a>\n }\n @if (hasAccess) {\n <a class=\"me-2 my-1\"\n aria-label=\"Edit Group\"\n (click)=\"editGroup(group.id)\"><i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i></a>\n }\n <a class=\"me-2 my-1\"\n aria-label=\"Members\"\n [routerLink]=\"[group.id, 'members']\"><i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </a>\n <a class=\"communications me-2 my-1\"\n aria-label=\"Communications\"\n (click)=\"navigateToCommunications(group.id)\"><i class=\"fa fa-comments cta2-icon\" aria-hidden=\"true\"></i></a>\n <a class=\"communications my-1\"\n aria-label=\"Documents\"\n (click)=\"navigateToDocumentations(group.id)\"><i class=\"fab fa-wikipedia-w cta1-icon\" aria-hidden=\"true\"></i></a>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </section>\n </div>\n @if (allGroups?.length === 0 && hasAccess && !isGroupOperations && isLoaded) {\n <div\n class=\"clear-both\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoTeamMessage' | transloco\"> </pw-no-data>\n </div>\n }\n @if (allGroups?.length === 0 && !hasAccess && !isGroupOperations && isLoaded) {\n <div\n class=\"clear-both\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoTeamMessageIfUser' | transloco\"> </pw-no-data>\n </div>\n }\n", styles: ["a.previous i{line-height:13px}.clear-both{clear:both}@media screen and (max-width:480px){.filter{flex:none;max-width:100%!important}.communications{margin-top:2%}}\n"], dependencies: [{ kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3$1.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i5$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i7.SlicePipe, name: "slice" }] }); }
1237
1442
  }
1238
1443
  __decorate([
1239
1444
  ValidateForm('form'),
@@ -1508,7 +1713,7 @@ class NumberPickerComponent {
1508
1713
  this.placeholder = this.placeholder ?? '';
1509
1714
  }
1510
1715
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: NumberPickerComponent, deps: [{ token: i1.NumberPickerService }], target: i0.ɵɵFactoryTarget.Component }); }
1511
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: NumberPickerComponent, isStandalone: false, selector: "pw-number-picker", inputs: { min: "min", showTooltip: "showTooltip", tooltipText: "tooltipText", max: "max", step: "step", value: "value", pickStartAfter: "pickStartAfter", pickTimer: "pickTimer", prefix: "prefix", postfix: "postfix", placeholder: "placeholder", buttonsOrientation: "buttonsOrientation", size: "size", customClass: "customClass", mouseWheel: "mouseWheel", arrowKeys: "arrowKeys", inputReadOnly: "inputReadOnly", showUpButton: "showUpButton", showDownButton: "showDownButton", inputId: "inputId" }, outputs: { valueChange: "valueChange", minReached: "minReached", maxReached: "maxReached", pickStarted: "pickStarted", pickStopped: "pickStopped", pickUpStarted: "pickUpStarted", pickUpStopped: "pickUpStopped", pickDownStarted: "pickDownStarted", pickDownStopped: "pickDownStopped" }, ngImport: i0, template: "<div class=\"input-group mb-3 input-{{ size }} {{ customClass.container }}\">\n <!-- Horizontal decrease button orientation -->\n @if (isHorizontal() && showDownButton) {\n <span\n class=\"input-group-text decrease {{ customClass.down }}\"\n (click)=\"onDecrease($event)\"\n (keydown.enter)=\"onDecrease($event)\"\n (mouseup)=\"onMouseUp($event, false)\"\n (mousedown)=\"onMouseDown($event, false)\">-</span>\n }\n <!-- Input prefix -->\n @if (prefix) {\n <span\n class=\"input-group-text {{ customClass.prefix }}\">{{ prefix }}\n </span>\n }\n <input type=\"number\"\n class=\"form-control\"\n [attr.id]=\"inputId\"\n name=\"input-spin-val\"\n [(ngModel)]=\"value\"\n [readOnly]=\"inputReadOnly\"\n (blur)=\"onBlur($event)\"\n (focus)=\"onFocus($event)\"\n (wheel)=\"mouseWheel && onMouseWheel($event)\"\n (keyup)=\"arrowKeys && onKeyUp($event)\"\n (keydown.enter)=\"arrowKeys && onKeyDown($event)\"\n (keydown.arrowup)=\"arrowKeys && onIncrease($event)\"\n (keydown.arrowdown)=\"arrowKeys && onDecrease($event)\"\n (change)=\"onValueChange($event)\"\n [placeholder]=\"placeholder\" />\n <!-- Input postfix -->\n\n @if (postfix) {\n <span\n class=\"input-group-text {{ customClass.postfix }}\"\n [style.borderLeft]=\"'0'\">{{postfix}}\n @if (showTooltip && tooltipText) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-info-circle\"></i>\n </span>\n }\n </span>\n }\n\n <!-- Horizontal increase button orientation -->\n @if (isHorizontal() && showUpButton) {\n <span\n class=\"input-group-text increase {{ customClass.up }}\"\n [style.borderLeft]=\"!postfix ? '0' : ''\"\n (click)=\"onIncrease($event)\"\n (keydown.enter)=\"onIncrease($event)\"\n (mouseup)=\"onMouseUp($event)\"\n (mousedown)=\"onMouseDown($event)\">+</span>\n }\n <!-- Vertical buttons orientation -->\n @if (!isHorizontal()) {\n <span\n class=\"input-group-text vertical p-0\">\n @if (showUpButton) {\n <span\n class=\"{{ customClass.up }}\"\n (click)=\"onIncrease($event)\"\n (keydown.enter)=\"onIncrease($event)\"\n (mouseup)=\"onMouseUp($event)\"\n (mousedown)=\"onMouseDown($event)\">+</span>\n }\n @if (showDownButton) {\n <span\n class=\"{{ customClass.down }}\"\n (keydown.enter)=\"onDecrease($event)\"\n (click)=\"onDecrease($event)\"\n (mouseup)=\"onMouseUp($event, false)\"\n (mousedown)=\"onMouseDown($event, false)\">-</span>\n }\n </span>\n }\n</div>\n", styles: ["input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{appearance:none;margin:0}.increase:hover,.decrease:hover{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;background-color:#d8d8d8}.increase{border-top-right-radius:3px!important;border-bottom-right-radius:3px!important}.vertical{display:flex;justify-content:center;flex-direction:column;text-align:center;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer}.vertical span{line-height:15px}.input-md .vertical span,.input-sm .vertical span{padding:2px 10px}.input-lg .vertical span{padding:4px 10px}.input-xlg .vertical span{padding:7px 10px}.input-md,.input-medium{height:45px}.input-lg,.input-large{height:50px}.input-xlg,.input-xlarge{height:75px}.input-md input,.input-medium input,.input-md span,.input-medium span{font-size:22px}.input-lg input,.input-large input,.input-lg span,.input-large span{font-size:25px}.input-xlg input,.input-xlarge input,.input-xlg span,.input-xlarge span{font-size:38px}\n"], dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$2.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] }); }
1716
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: NumberPickerComponent, isStandalone: false, selector: "pw-number-picker", inputs: { min: "min", showTooltip: "showTooltip", tooltipText: "tooltipText", max: "max", step: "step", value: "value", pickStartAfter: "pickStartAfter", pickTimer: "pickTimer", prefix: "prefix", postfix: "postfix", placeholder: "placeholder", buttonsOrientation: "buttonsOrientation", size: "size", customClass: "customClass", mouseWheel: "mouseWheel", arrowKeys: "arrowKeys", inputReadOnly: "inputReadOnly", showUpButton: "showUpButton", showDownButton: "showDownButton", inputId: "inputId" }, outputs: { valueChange: "valueChange", minReached: "minReached", maxReached: "maxReached", pickStarted: "pickStarted", pickStopped: "pickStopped", pickUpStarted: "pickUpStarted", pickUpStopped: "pickUpStopped", pickDownStarted: "pickDownStarted", pickDownStopped: "pickDownStopped" }, ngImport: i0, template: "<div class=\"input-group mb-3 input-{{ size }} {{ customClass.container }}\">\n <!-- Horizontal decrease button orientation -->\n @if (isHorizontal() && showDownButton) {\n <span\n class=\"input-group-text decrease {{ customClass.down }}\"\n (click)=\"onDecrease($event)\"\n (keydown.enter)=\"onDecrease($event)\"\n (mouseup)=\"onMouseUp($event, false)\"\n (mousedown)=\"onMouseDown($event, false)\">-</span>\n }\n <!-- Input prefix -->\n @if (prefix) {\n <span\n class=\"input-group-text {{ customClass.prefix }}\">{{ prefix }}\n </span>\n }\n <input type=\"number\"\n class=\"form-control\"\n [attr.id]=\"inputId\"\n name=\"input-spin-val\"\n [(ngModel)]=\"value\"\n [readOnly]=\"inputReadOnly\"\n (blur)=\"onBlur($event)\"\n (focus)=\"onFocus($event)\"\n (wheel)=\"mouseWheel && onMouseWheel($event)\"\n (keyup)=\"arrowKeys && onKeyUp($event)\"\n (keydown.enter)=\"arrowKeys && onKeyDown($event)\"\n (keydown.arrowup)=\"arrowKeys && onIncrease($event)\"\n (keydown.arrowdown)=\"arrowKeys && onDecrease($event)\"\n (change)=\"onValueChange($event)\"\n [placeholder]=\"placeholder\" />\n <!-- Input postfix -->\n\n @if (postfix) {\n <span\n class=\"input-group-text {{ customClass.postfix }}\"\n [style.borderLeft]=\"'0'\">{{postfix}}\n @if (showTooltip && tooltipText) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-info-circle\"></i>\n </span>\n }\n </span>\n }\n\n <!-- Horizontal increase button orientation -->\n @if (isHorizontal() && showUpButton) {\n <span\n class=\"input-group-text increase {{ customClass.up }}\"\n [style.borderLeft]=\"!postfix ? '0' : ''\"\n (click)=\"onIncrease($event)\"\n (keydown.enter)=\"onIncrease($event)\"\n (mouseup)=\"onMouseUp($event)\"\n (mousedown)=\"onMouseDown($event)\">+</span>\n }\n <!-- Vertical buttons orientation -->\n @if (!isHorizontal()) {\n <span\n class=\"input-group-text vertical p-0\">\n @if (showUpButton) {\n <span\n class=\"{{ customClass.up }}\"\n (click)=\"onIncrease($event)\"\n (keydown.enter)=\"onIncrease($event)\"\n (mouseup)=\"onMouseUp($event)\"\n (mousedown)=\"onMouseDown($event)\">+</span>\n }\n @if (showDownButton) {\n <span\n class=\"{{ customClass.down }}\"\n (keydown.enter)=\"onDecrease($event)\"\n (click)=\"onDecrease($event)\"\n (mouseup)=\"onMouseUp($event, false)\"\n (mousedown)=\"onMouseDown($event, false)\">-</span>\n }\n </span>\n }\n</div>\n", styles: ["input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{appearance:none;margin:0}.increase:hover,.decrease:hover{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;background-color:#d8d8d8}.increase{border-top-right-radius:3px!important;border-bottom-right-radius:3px!important}.vertical{display:flex;justify-content:center;flex-direction:column;text-align:center;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer}.vertical span{line-height:15px}.input-md .vertical span,.input-sm .vertical span{padding:2px 10px}.input-lg .vertical span{padding:4px 10px}.input-xlg .vertical span{padding:7px 10px}.input-md,.input-medium{height:45px}.input-lg,.input-large{height:50px}.input-xlg,.input-xlarge{height:75px}.input-md input,.input-medium input,.input-md span,.input-medium span{font-size:22px}.input-lg input,.input-large input,.input-lg span,.input-large span{font-size:25px}.input-xlg input,.input-xlarge input,.input-xlg span,.input-xlarge span{font-size:38px}\n"], dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] }); }
1512
1717
  }
1513
1718
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: NumberPickerComponent, decorators: [{
1514
1719
  type: Component,
@@ -1607,13 +1812,13 @@ class PasswordValidationComponent extends AppBaseComponent {
1607
1812
  });
1608
1813
  }
1609
1814
  }
1610
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PasswordValidationComponent, deps: [{ token: i0.Injector }, { token: i3$1.NgbModal }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1611
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: PasswordValidationComponent, isStandalone: false, selector: "pw-password-validation", inputs: { confirmMessage: "confirmMessage" }, outputs: { successEvent: "successEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Confirm</h5>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"modal-body\">\n <strong class=\"p3\">{{ confirmMessage | transloco }}</strong>\n <div>\n <ng-content></ng-content>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <input type=\"password\"\n #passwordRef\n [(ngModel)]=\"password\"\n class=\"form-control\"\n placeholder=\"Current Password\" id=\"input_password_992\" name=\"input_password_992\" />\n </div>\n </div>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <button [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary float-end\"\n type=\"button\"\n (click)=\"validatePassword()\">\n {{ 'Button.Confirm' | transloco }}\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
1815
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PasswordValidationComponent, deps: [{ token: i0.Injector }, { token: i3$2.NgbModal }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1816
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: PasswordValidationComponent, isStandalone: false, selector: "pw-password-validation", inputs: { confirmMessage: "confirmMessage" }, outputs: { successEvent: "successEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Confirm</h5>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"modal-body\">\n <strong class=\"p3\">{{ confirmMessage | transloco }}</strong>\n <div>\n <ng-content></ng-content>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <input type=\"password\"\n #passwordRef\n [(ngModel)]=\"password\"\n class=\"form-control\"\n placeholder=\"Current Password\" id=\"input_password_992\" name=\"input_password_992\" />\n </div>\n </div>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <button [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary float-end\"\n type=\"button\"\n (click)=\"validatePassword()\">\n {{ 'Button.Confirm' | transloco }}\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$1.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
1612
1817
  }
1613
1818
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PasswordValidationComponent, decorators: [{
1614
1819
  type: Component,
1615
1820
  args: [{ selector: 'pw-password-validation', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Confirm</h5>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"modal-body\">\n <strong class=\"p3\">{{ confirmMessage | transloco }}</strong>\n <div>\n <ng-content></ng-content>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <input type=\"password\"\n #passwordRef\n [(ngModel)]=\"password\"\n class=\"form-control\"\n placeholder=\"Current Password\" id=\"input_password_992\" name=\"input_password_992\" />\n </div>\n </div>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <button [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary float-end\"\n type=\"button\"\n (click)=\"validatePassword()\">\n {{ 'Button.Confirm' | transloco }}\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n" }]
1616
- }], ctorParameters: () => [{ type: i0.Injector }, { type: i3$1.NgbModal }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
1821
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: i3$2.NgbModal }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
1617
1822
  type: ViewChild,
1618
1823
  args: ['content', { static: true }]
1619
1824
  }], confirmMessage: [{
@@ -1654,7 +1859,7 @@ class PermissionTreeComponent {
1654
1859
  if (!this.data || !this._$tree) {
1655
1860
  return;
1656
1861
  }
1657
- const treeData = map(this.data.permissions, item => {
1862
+ const treeData = map$1(this.data.permissions, item => {
1658
1863
  return {
1659
1864
  id: item.name,
1660
1865
  parent: item.parentName ?? '#',
@@ -1832,7 +2037,7 @@ class PrivacyAndTosComponent extends AppBaseComponent {
1832
2037
  });
1833
2038
  }
1834
2039
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PrivacyAndTosComponent, deps: [{ token: i1$1.AdminService }, { token: i0.Injector }, { token: DOCUMENT }, { token: i2$2.DomSanitizer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
1835
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: PrivacyAndTosComponent, isStandalone: false, selector: "pw-privacy-and-tos", inputs: { productId: "productId" }, usesInheritance: true, ngImport: i0, template: "@if (isPublic) {\n <pw-header [landing]=\"false\"></pw-header>\n}\n\n@if (!isPublic) {\n <div class=\"col-12 d-flex\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"mt-3\">{{ productName }}</h3>\n </div>\n }\n\n\n\n\n <div [ngClass]=\"{ 'container pw-tab overflow-hidden': isPublic }\" >\n <div [ngClass]=\"{ dashboard: isPublic }\">\n <div [ngClass]=\"{ 'dashboard-body': isPublic }\">\n <div [ngClass]=\"{ 'mt-5': isPublic }\">\n @if (isPublic) {\n <h3>{{ product }}</h3>\n }\n <div>\n\n <ul ngbNav\n #nav=\"ngbNav\"\n [(activeId)]=\"tabId\"\n class=\"nav-tabs\">\n <li [ngbNavItem]=\"'privacy-policy'\">\n <a ngbNavLink>Privacy policy</a>\n <ng-template ngbNavContent>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body pt-1\">\n <div class=\"row\">\n <div class=\"col-12 terms-of-service\">\n <h3>Privacy policy</h3>\n <div class=\"clearfix\"></div>\n <div class=\"ql-container ql-snow body-quill\">\n <div class=\"ql-editor\"\n [innerHTML]=\"data?.privacy\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </li>\n <li [ngbNavItem]=\"'terms-of-service'\">\n <a ngbNavLink>Terms of Services</a>\n <ng-template ngbNavContent>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body pt-1\">\n <div class=\"row\">\n <div class=\"col-12 terms-of-service\">\n <h3>Terms of Services</h3>\n <div class=\"clearfix\"></div>\n <div class=\"ql-container ql-snow body-quill\">\n <div class=\"ql-editor\"\n [innerHTML]=\"data?.tos\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </li>\n </ul>\n </div>\n @if (!isLoaded) {\n <div class=\"w-100 text-center p-2 mt-5\">\n <p-progressSpinner strokeWidth=\"2\"></p-progressSpinner>\n </div>\n }\n @if (isLoaded) {\n <div [ngbNavOutlet]=\"nav\"></div>\n }\n </div>\n </div>\n </div>\n </div>\n", styles: ["::ng-deep .terms-of-service ul{list-style:disc!important;padding-left:40px!important}.ql-container{max-width:1000px;margin:0 auto;resize:none!important}\n"], dependencies: [{ kind: "directive", type: i3$1.NgbNavContent, selector: "ng-template[ngbNavContent]" }, { kind: "directive", type: i3$1.NgbNav, selector: "[ngbNav]", inputs: ["activeId", "animation", "destroyOnHide", "orientation", "roles", "keyboard"], outputs: ["activeIdChange", "shown", "hidden", "navChange"], exportAs: ["ngbNav"] }, { kind: "directive", type: i3$1.NgbNavItem, selector: "[ngbNavItem]", inputs: ["destroyOnHide", "disabled", "domId", "ngbNavItem"], outputs: ["shown", "hidden"], exportAs: ["ngbNavItem"] }, { kind: "directive", type: i3$1.NgbNavItemRole, selector: "[ngbNavItem]:not(ng-container)" }, { kind: "directive", type: i3$1.NgbNavLink, selector: "a[ngbNavLink]" }, { kind: "directive", type: i3$1.NgbNavLinkBase, selector: "[ngbNavLink]" }, { kind: "component", type: i3$1.NgbNavOutlet, selector: "[ngbNavOutlet]", inputs: ["paneRole", "ngbNavOutlet"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeaderComponent, selector: "pw-header", inputs: ["landing"] }] }); }
2040
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: PrivacyAndTosComponent, isStandalone: false, selector: "pw-privacy-and-tos", inputs: { productId: "productId" }, usesInheritance: true, ngImport: i0, template: "@if (isPublic) {\n <pw-header [landing]=\"false\"></pw-header>\n}\n\n@if (!isPublic) {\n <div class=\"col-12 d-flex\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"mt-3\">{{ productName }}</h3>\n </div>\n }\n\n\n\n\n <div [ngClass]=\"{ 'container pw-tab overflow-hidden': isPublic }\" >\n <div [ngClass]=\"{ dashboard: isPublic }\">\n <div [ngClass]=\"{ 'dashboard-body': isPublic }\">\n <div [ngClass]=\"{ 'mt-5': isPublic }\">\n @if (isPublic) {\n <h3>{{ product }}</h3>\n }\n <div>\n\n <ul ngbNav\n #nav=\"ngbNav\"\n [(activeId)]=\"tabId\"\n class=\"nav-tabs\">\n <li [ngbNavItem]=\"'privacy-policy'\">\n <a ngbNavLink>Privacy policy</a>\n <ng-template ngbNavContent>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body pt-1\">\n <div class=\"row\">\n <div class=\"col-12 terms-of-service\">\n <h3>Privacy policy</h3>\n <div class=\"clearfix\"></div>\n <div class=\"ql-container ql-snow body-quill\">\n <div class=\"ql-editor\"\n [innerHTML]=\"data?.privacy\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </li>\n <li [ngbNavItem]=\"'terms-of-service'\">\n <a ngbNavLink>Terms of Services</a>\n <ng-template ngbNavContent>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body pt-1\">\n <div class=\"row\">\n <div class=\"col-12 terms-of-service\">\n <h3>Terms of Services</h3>\n <div class=\"clearfix\"></div>\n <div class=\"ql-container ql-snow body-quill\">\n <div class=\"ql-editor\"\n [innerHTML]=\"data?.tos\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </li>\n </ul>\n </div>\n @if (!isLoaded) {\n <div class=\"w-100 text-center p-2 mt-5\">\n <p-progressSpinner strokeWidth=\"2\"></p-progressSpinner>\n </div>\n }\n @if (isLoaded) {\n <div [ngbNavOutlet]=\"nav\"></div>\n }\n </div>\n </div>\n </div>\n </div>\n", styles: ["::ng-deep .terms-of-service ul{list-style:disc!important;padding-left:40px!important}.ql-container{max-width:1000px;margin:0 auto;resize:none!important}\n"], dependencies: [{ kind: "directive", type: i3$2.NgbNavContent, selector: "ng-template[ngbNavContent]" }, { kind: "directive", type: i3$2.NgbNav, selector: "[ngbNav]", inputs: ["activeId", "animation", "destroyOnHide", "orientation", "roles", "keyboard"], outputs: ["activeIdChange", "shown", "hidden", "navChange"], exportAs: ["ngbNav"] }, { kind: "directive", type: i3$2.NgbNavItem, selector: "[ngbNavItem]", inputs: ["destroyOnHide", "disabled", "domId", "ngbNavItem"], outputs: ["shown", "hidden"], exportAs: ["ngbNavItem"] }, { kind: "directive", type: i3$2.NgbNavItemRole, selector: "[ngbNavItem]:not(ng-container)" }, { kind: "directive", type: i3$2.NgbNavLink, selector: "a[ngbNavLink]" }, { kind: "directive", type: i3$2.NgbNavLinkBase, selector: "[ngbNavLink]" }, { kind: "component", type: i3$2.NgbNavOutlet, selector: "[ngbNavOutlet]", inputs: ["paneRole", "ngbNavOutlet"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeaderComponent, selector: "pw-header", inputs: ["landing"] }] }); }
1836
2041
  }
1837
2042
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PrivacyAndTosComponent, decorators: [{
1838
2043
  type: Component,
@@ -2024,7 +2229,7 @@ class InputContainerComponent {
2024
2229
  useExisting: InputContainerComponent,
2025
2230
  multi: true
2026
2231
  }
2027
- ], ngImport: i0, template: "@if (useAriaLabelledbyOnly) {\n <span class=\"pw-input-container-label mb-2 d-block\" [attr.id]=\"controlId ? (controlId + '-label') : null\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span [ngClass]=\"{ 'left-info-circle': isLeftTooltip }\" class=\"info-circle tooltip-wrap ms-1\">\n <span class=\"tooltiptext gradient-custom-branding\" [ngClass]=\"{ 'left-field-tooltip': isLeftTooltip }\">\n {{ tooltipText }}\n </span>\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </span>\n}\n@if (!useAriaLabelledbyOnly) {\n <label class=\"pw-input-container-label mb-2\" [attr.for]=\"controlId || name\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span [ngClass]=\"{ 'left-info-circle': isLeftTooltip }\" class=\"info-circle tooltip-wrap ms-1\">\n <span class=\"tooltiptext gradient-custom-branding\" [ngClass]=\"{ 'left-field-tooltip': isLeftTooltip }\">\n {{ tooltipText }}\n </span>\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </label>\n}\n\n<div class=\"mb-3\">\n <ng-content></ng-content>\n @if (control?.errors) {\n <pw-field-error-display [displayError]=\"control?.invalid && control?.touched\"\n [errorMsg]=\"errorMsg | transloco\">\n </pw-field-error-display>\n }\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.pw-input-container-label{display:block;color:gray;font-size:.75rem;font-weight:500;letter-spacing:2px;text-transform:uppercase}.mandatory:after{color:#ff586b;content:\"*\";padding-left:2px;font-size:15px}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$2.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i4$2.FieldErrorDisplayComponent, selector: "pw-field-error-display", inputs: ["errorMsg", "displayError"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
2232
+ ], ngImport: i0, template: "@if (useAriaLabelledbyOnly) {\n <span class=\"pw-input-container-label mb-2 d-block\" [attr.id]=\"controlId ? (controlId + '-label') : null\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span class=\"info-circle tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </span>\n}\n@if (!useAriaLabelledbyOnly) {\n <label class=\"pw-input-container-label mb-2\" [attr.for]=\"controlId || name\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span class=\"info-circle tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </label>\n}\n\n<div class=\"mb-3\">\n <ng-content></ng-content>\n @if (control?.errors) {\n <pw-field-error-display [displayError]=\"control?.invalid && control?.touched\"\n [errorMsg]=\"errorMsg | transloco\">\n </pw-field-error-display>\n }\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.pw-input-container-label{display:block;color:gray;font-size:.75rem;font-weight:500;letter-spacing:2px;text-transform:uppercase}.mandatory:after{color:#ff586b;content:\"*\";padding-left:2px;font-size:15px}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i4$2.FieldErrorDisplayComponent, selector: "pw-field-error-display", inputs: ["errorMsg", "displayError"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
2028
2233
  }
2029
2234
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: InputContainerComponent, decorators: [{
2030
2235
  type: Component,
@@ -2035,7 +2240,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
2035
2240
  useExisting: InputContainerComponent,
2036
2241
  multi: true
2037
2242
  }
2038
- ], standalone: false, template: "@if (useAriaLabelledbyOnly) {\n <span class=\"pw-input-container-label mb-2 d-block\" [attr.id]=\"controlId ? (controlId + '-label') : null\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span [ngClass]=\"{ 'left-info-circle': isLeftTooltip }\" class=\"info-circle tooltip-wrap ms-1\">\n <span class=\"tooltiptext gradient-custom-branding\" [ngClass]=\"{ 'left-field-tooltip': isLeftTooltip }\">\n {{ tooltipText }}\n </span>\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </span>\n}\n@if (!useAriaLabelledbyOnly) {\n <label class=\"pw-input-container-label mb-2\" [attr.for]=\"controlId || name\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span [ngClass]=\"{ 'left-info-circle': isLeftTooltip }\" class=\"info-circle tooltip-wrap ms-1\">\n <span class=\"tooltiptext gradient-custom-branding\" [ngClass]=\"{ 'left-field-tooltip': isLeftTooltip }\">\n {{ tooltipText }}\n </span>\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </label>\n}\n\n<div class=\"mb-3\">\n <ng-content></ng-content>\n @if (control?.errors) {\n <pw-field-error-display [displayError]=\"control?.invalid && control?.touched\"\n [errorMsg]=\"errorMsg | transloco\">\n </pw-field-error-display>\n }\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.pw-input-container-label{display:block;color:gray;font-size:.75rem;font-weight:500;letter-spacing:2px;text-transform:uppercase}.mandatory:after{color:#ff586b;content:\"*\";padding-left:2px;font-size:15px}\n"] }]
2243
+ ], standalone: false, template: "@if (useAriaLabelledbyOnly) {\n <span class=\"pw-input-container-label mb-2 d-block\" [attr.id]=\"controlId ? (controlId + '-label') : null\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span class=\"info-circle tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </span>\n}\n@if (!useAriaLabelledbyOnly) {\n <label class=\"pw-input-container-label mb-2\" [attr.for]=\"controlId || name\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span class=\"info-circle tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </label>\n}\n\n<div class=\"mb-3\">\n <ng-content></ng-content>\n @if (control?.errors) {\n <pw-field-error-display [displayError]=\"control?.invalid && control?.touched\"\n [errorMsg]=\"errorMsg | transloco\">\n </pw-field-error-display>\n }\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.pw-input-container-label{display:block;color:gray;font-size:.75rem;font-weight:500;letter-spacing:2px;text-transform:uppercase}.mandatory:after{color:#ff586b;content:\"*\";padding-left:2px;font-size:15px}\n"] }]
2039
2244
  }], ctorParameters: () => [{ type: i2$1.ControlContainer, decorators: [{
2040
2245
  type: Optional
2041
2246
  }, {
@@ -2409,7 +2614,7 @@ class CollapsibleSidebarSuperAdminGuard {
2409
2614
  * Emits true when the signed-in user has {@link PermissionService.isSuperAdmin}.
2410
2615
  * UX-only; backend must still enforce permissions.
2411
2616
  */
2412
- this.canAccessSidebar$ = this.userService.getUserState().pipe(map$1(state => CollapsibleSidebarSuperAdminGuard.userIsSuperAdmin(state?.currentUser)), distinctUntilChanged());
2617
+ this.canAccessSidebar$ = this.userService.getUserState().pipe(map(state => CollapsibleSidebarSuperAdminGuard.userIsSuperAdmin(state?.currentUser)), distinctUntilChanged());
2413
2618
  }
2414
2619
  /**
2415
2620
  * Same rule as {@link PermissionService#isSuperAdmin}, safe when user is not loaded.