@posiwise/shared-components 0.0.158 → 0.0.159
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$
|
|
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 {
|
|
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$
|
|
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(
|
|
97
|
-
this.
|
|
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.
|
|
255
|
+
this.conversationId = null;
|
|
256
|
+
this.storage = null;
|
|
104
257
|
this.destroy$ = new Subject();
|
|
258
|
+
this.diffRows = diffRowsFrom;
|
|
105
259
|
}
|
|
106
260
|
ngOnInit() {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
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
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
this.
|
|
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.
|
|
143
|
-
|
|
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:
|
|
147
|
-
|
|
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
|
-
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
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);
|
|
357
|
+
}
|
|
358
|
+
else {
|
|
359
|
+
this.pushAssistant(response.reason ?? 'I could not complete that request.');
|
|
178
360
|
}
|
|
179
|
-
|
|
180
|
-
|
|
361
|
+
this.storage?.persistMessages(this.messages);
|
|
362
|
+
this.loading = false;
|
|
363
|
+
this.cdr.markForCheck();
|
|
181
364
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
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
|
-
|
|
197
|
-
|
|
198
|
-
});
|
|
371
|
+
window.location.assign(url);
|
|
372
|
+
return;
|
|
199
373
|
}
|
|
200
|
-
|
|
201
|
-
this.pushAssistant(
|
|
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
|
-
|
|
206
|
-
this.pushAssistant(text);
|
|
384
|
+
this.pushAssistant(response.response ?? JSON.stringify(response.tool_result ?? {}, null, 2));
|
|
207
385
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return false;
|
|
396
|
+
persistConversationId(id) {
|
|
397
|
+
if (!id || id === this.conversationId) {
|
|
398
|
+
return;
|
|
221
399
|
}
|
|
222
|
-
|
|
223
|
-
|
|
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.
|
|
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.
|
|
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,
|
|
@@ -413,7 +591,20 @@ class CollapsibleSidebarComponent {
|
|
|
413
591
|
this.isExpanded = isExpanded;
|
|
414
592
|
this.cdr.markForCheck();
|
|
415
593
|
});
|
|
416
|
-
|
|
594
|
+
}
|
|
595
|
+
ngAfterViewInit() {
|
|
596
|
+
// `sidebarContent$` is a BehaviorSubject — it emits its current value
|
|
597
|
+
// SYNCHRONOUSLY on subscribe. If we subscribed in ngOnInit, the
|
|
598
|
+
// first emission would arrive before `contentContainer` (a
|
|
599
|
+
// @ViewChild) is bound, and `loadComponent()` would silently bail
|
|
600
|
+
// out with `Content container not found`. That used to be benign
|
|
601
|
+
// because `unregisterContent` nulled the slot on dashboard destroy
|
|
602
|
+
// (so the first emission was null), but ticket #4167's
|
|
603
|
+
// open-on-navigate-back fix keeps the slot populated — without
|
|
604
|
+
// moving the subscription here, the new sidebar instance receives
|
|
605
|
+
// the existing content reference too early and never mounts the
|
|
606
|
+
// chat. Subscribe AFTER the view is initialised so the first
|
|
607
|
+
// emission lands with `contentContainer` already wired up.
|
|
417
608
|
this.sidebarService.sidebarContent$.pipe(takeUntil(this.destroy$)).subscribe(content => {
|
|
418
609
|
this.currentContent = content;
|
|
419
610
|
if (content) {
|
|
@@ -424,8 +615,6 @@ class CollapsibleSidebarComponent {
|
|
|
424
615
|
}
|
|
425
616
|
this.cdr.markForCheck();
|
|
426
617
|
});
|
|
427
|
-
}
|
|
428
|
-
ngAfterViewInit() {
|
|
429
618
|
// Double rAF: wait until after layout so we do not trigger transitions from mount → closed.
|
|
430
619
|
requestAnimationFrame(() => {
|
|
431
620
|
requestAnimationFrame(() => {
|
|
@@ -610,7 +799,7 @@ class HeaderComponent extends AppBaseComponent {
|
|
|
610
799
|
this.isMenuCollapsed = !this.isMenuCollapsed;
|
|
611
800
|
}
|
|
612
801
|
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" }] }); }
|
|
802
|
+
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
803
|
}
|
|
615
804
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HeaderComponent, decorators: [{
|
|
616
805
|
type: Component,
|
|
@@ -655,7 +844,7 @@ class NoDataComponent {
|
|
|
655
844
|
}
|
|
656
845
|
<ng-content></ng-content>
|
|
657
846
|
</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" }] }); }
|
|
847
|
+
`, 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
848
|
}
|
|
660
849
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: NoDataComponent, decorators: [{
|
|
661
850
|
type: Component,
|
|
@@ -829,13 +1018,13 @@ class EntityGroupComponent extends AppBaseComponent {
|
|
|
829
1018
|
ngOnDestroy() {
|
|
830
1019
|
super.ngOnDestroy();
|
|
831
1020
|
}
|
|
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$
|
|
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" }] }); }
|
|
1021
|
+
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 }); }
|
|
1022
|
+
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
1023
|
}
|
|
835
1024
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EntityGroupComponent, decorators: [{
|
|
836
1025
|
type: Component,
|
|
837
1026
|
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$
|
|
1027
|
+
}], ctorParameters: () => [{ type: i1.GroupService }, { type: i1.SubscriptionService }, { type: i3$2.NgbModal }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
|
|
839
1028
|
type: ViewChild,
|
|
840
1029
|
args: ['content', { static: true }]
|
|
841
1030
|
}] } });
|
|
@@ -1001,7 +1190,7 @@ class GroupDefinitionComponent extends AppBaseComponent {
|
|
|
1001
1190
|
super.ngOnDestroy();
|
|
1002
1191
|
}
|
|
1003
1192
|
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" }] }); }
|
|
1193
|
+
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
1194
|
}
|
|
1006
1195
|
__decorate([
|
|
1007
1196
|
ValidateForm('form'),
|
|
@@ -1233,7 +1422,7 @@ class GroupsComponent extends AppBaseComponent {
|
|
|
1233
1422
|
super.ngOnDestroy();
|
|
1234
1423
|
}
|
|
1235
1424
|
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" }] }); }
|
|
1425
|
+
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
1426
|
}
|
|
1238
1427
|
__decorate([
|
|
1239
1428
|
ValidateForm('form'),
|
|
@@ -1508,7 +1697,7 @@ class NumberPickerComponent {
|
|
|
1508
1697
|
this.placeholder = this.placeholder ?? '';
|
|
1509
1698
|
}
|
|
1510
1699
|
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$
|
|
1700
|
+
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
1701
|
}
|
|
1513
1702
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: NumberPickerComponent, decorators: [{
|
|
1514
1703
|
type: Component,
|
|
@@ -1607,13 +1796,13 @@ class PasswordValidationComponent extends AppBaseComponent {
|
|
|
1607
1796
|
});
|
|
1608
1797
|
}
|
|
1609
1798
|
}
|
|
1610
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PasswordValidationComponent, deps: [{ token: i0.Injector }, { token: i3$
|
|
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" }] }); }
|
|
1799
|
+
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 }); }
|
|
1800
|
+
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
1801
|
}
|
|
1613
1802
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PasswordValidationComponent, decorators: [{
|
|
1614
1803
|
type: Component,
|
|
1615
1804
|
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$
|
|
1805
|
+
}], ctorParameters: () => [{ type: i0.Injector }, { type: i3$2.NgbModal }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
|
|
1617
1806
|
type: ViewChild,
|
|
1618
1807
|
args: ['content', { static: true }]
|
|
1619
1808
|
}], confirmMessage: [{
|
|
@@ -1654,7 +1843,7 @@ class PermissionTreeComponent {
|
|
|
1654
1843
|
if (!this.data || !this._$tree) {
|
|
1655
1844
|
return;
|
|
1656
1845
|
}
|
|
1657
|
-
const treeData = map(this.data.permissions, item => {
|
|
1846
|
+
const treeData = map$1(this.data.permissions, item => {
|
|
1658
1847
|
return {
|
|
1659
1848
|
id: item.name,
|
|
1660
1849
|
parent: item.parentName ?? '#',
|
|
@@ -1832,7 +2021,7 @@ class PrivacyAndTosComponent extends AppBaseComponent {
|
|
|
1832
2021
|
});
|
|
1833
2022
|
}
|
|
1834
2023
|
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$
|
|
2024
|
+
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
2025
|
}
|
|
1837
2026
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PrivacyAndTosComponent, decorators: [{
|
|
1838
2027
|
type: Component,
|
|
@@ -2024,7 +2213,7 @@ class InputContainerComponent {
|
|
|
2024
2213
|
useExisting: InputContainerComponent,
|
|
2025
2214
|
multi: true
|
|
2026
2215
|
}
|
|
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
|
|
2216
|
+
], 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
2217
|
}
|
|
2029
2218
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: InputContainerComponent, decorators: [{
|
|
2030
2219
|
type: Component,
|
|
@@ -2035,7 +2224,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
2035
2224
|
useExisting: InputContainerComponent,
|
|
2036
2225
|
multi: true
|
|
2037
2226
|
}
|
|
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
|
|
2227
|
+
], 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
2228
|
}], ctorParameters: () => [{ type: i2$1.ControlContainer, decorators: [{
|
|
2040
2229
|
type: Optional
|
|
2041
2230
|
}, {
|
|
@@ -2409,7 +2598,7 @@ class CollapsibleSidebarSuperAdminGuard {
|
|
|
2409
2598
|
* Emits true when the signed-in user has {@link PermissionService.isSuperAdmin}.
|
|
2410
2599
|
* UX-only; backend must still enforce permissions.
|
|
2411
2600
|
*/
|
|
2412
|
-
this.canAccessSidebar$ = this.userService.getUserState().pipe(map
|
|
2601
|
+
this.canAccessSidebar$ = this.userService.getUserState().pipe(map(state => CollapsibleSidebarSuperAdminGuard.userIsSuperAdmin(state?.currentUser)), distinctUntilChanged());
|
|
2413
2602
|
}
|
|
2414
2603
|
/**
|
|
2415
2604
|
* Same rule as {@link PermissionService#isSuperAdmin}, safe when user is not loaded.
|