@posiwise/shared-components 0.0.158 → 0.0.160
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -9,7 +9,7 @@ import { NavigationEnd, RouterModule } from '@angular/router';
|
|
|
9
9
|
import * as i1$3 from '@posiwise/app-loader';
|
|
10
10
|
import { AppLoaderModule } from '@posiwise/app-loader';
|
|
11
11
|
import { CoreTranslocoModule } from '@posiwise/core-transloco';
|
|
12
|
-
import * as i3 from '@posiwise/directives';
|
|
12
|
+
import * as i3$1 from '@posiwise/directives';
|
|
13
13
|
import { DirectivesModule } from '@posiwise/directives';
|
|
14
14
|
import { PipesModule } from '@posiwise/pipes';
|
|
15
15
|
import * as i4$2 from '@posiwise/utils';
|
|
@@ -31,23 +31,24 @@ import * as i6 from 'primeng/table';
|
|
|
31
31
|
import { TableModule } from 'primeng/table';
|
|
32
32
|
import * as i2$3 from 'primeng/tabs';
|
|
33
33
|
import { TabsModule } from 'primeng/tabs';
|
|
34
|
-
import * as i3$
|
|
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
|
-
buildHelpReply() {
|
|
169
|
-
return 'I could not map that to a tool yet. Try: “show my API stats”, “usage”, or “get user stats”.';
|
|
170
|
-
}
|
|
171
|
-
resolveToolName(text) {
|
|
172
|
-
const lower = text.toLowerCase();
|
|
173
|
-
if (this.tools.some(t => t.name === 'get_user_stats')) {
|
|
174
|
-
if (/\b(stats?|usage|hits?|api|account|quota|get_user_stats)\b/i.test(lower) ||
|
|
175
|
-
lower.includes('user stats')) {
|
|
176
|
-
return 'get_user_stats';
|
|
177
|
-
}
|
|
355
|
+
else if (response.result_status === 'success') {
|
|
356
|
+
this.applySuccessResult(response);
|
|
178
357
|
}
|
|
179
|
-
|
|
180
|
-
|
|
358
|
+
else {
|
|
359
|
+
this.pushAssistant(response.reason ?? 'I could not complete that request.');
|
|
360
|
+
}
|
|
361
|
+
this.storage?.persistMessages(this.messages);
|
|
362
|
+
this.loading = false;
|
|
363
|
+
this.cdr.markForCheck();
|
|
181
364
|
}
|
|
182
|
-
|
|
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,
|
|
@@ -406,6 +584,22 @@ class CollapsibleSidebarComponent {
|
|
|
406
584
|
this.destroy$ = new Subject();
|
|
407
585
|
}
|
|
408
586
|
ngOnInit() {
|
|
587
|
+
// Self-register the PosiWise Brain (MCP) panel so every consumer
|
|
588
|
+
// frontend (main-frontend, cloudolive-frontend, products-frontend,
|
|
589
|
+
// angular-frontend-template) behaves identically just by rendering
|
|
590
|
+
// <pw-collapsible-sidebar> — no per-app dashboard-layout wiring. The
|
|
591
|
+
// shared @posiwise/core-components navbar emits the trigger
|
|
592
|
+
// (pwCollapsibleSidebarTrigger [contentId]="'posiwise-brain'") in all
|
|
593
|
+
// of them; without this registration `loadContent()` silently bails
|
|
594
|
+
// and the widget never opens. `registerContent` is idempotent (Map
|
|
595
|
+
// keyed by id), so remount / multiple hosts are safe. The slot is
|
|
596
|
+
// intentionally NOT unregistered on destroy (ticket #4167: sticky
|
|
597
|
+
// BehaviorSubject state across dashboard remount).
|
|
598
|
+
this.sidebarService.registerContent({
|
|
599
|
+
id: 'posiwise-brain',
|
|
600
|
+
title: 'PosiWise Brain',
|
|
601
|
+
component: PwBrainChatComponent
|
|
602
|
+
});
|
|
409
603
|
// Subscribe to expanded state
|
|
410
604
|
this.sidebarService.sidebarExpanded$
|
|
411
605
|
.pipe(takeUntil(this.destroy$))
|
|
@@ -413,7 +607,20 @@ class CollapsibleSidebarComponent {
|
|
|
413
607
|
this.isExpanded = isExpanded;
|
|
414
608
|
this.cdr.markForCheck();
|
|
415
609
|
});
|
|
416
|
-
|
|
610
|
+
}
|
|
611
|
+
ngAfterViewInit() {
|
|
612
|
+
// `sidebarContent$` is a BehaviorSubject — it emits its current value
|
|
613
|
+
// SYNCHRONOUSLY on subscribe. If we subscribed in ngOnInit, the
|
|
614
|
+
// first emission would arrive before `contentContainer` (a
|
|
615
|
+
// @ViewChild) is bound, and `loadComponent()` would silently bail
|
|
616
|
+
// out with `Content container not found`. That used to be benign
|
|
617
|
+
// because `unregisterContent` nulled the slot on dashboard destroy
|
|
618
|
+
// (so the first emission was null), but ticket #4167's
|
|
619
|
+
// open-on-navigate-back fix keeps the slot populated — without
|
|
620
|
+
// moving the subscription here, the new sidebar instance receives
|
|
621
|
+
// the existing content reference too early and never mounts the
|
|
622
|
+
// chat. Subscribe AFTER the view is initialised so the first
|
|
623
|
+
// emission lands with `contentContainer` already wired up.
|
|
417
624
|
this.sidebarService.sidebarContent$.pipe(takeUntil(this.destroy$)).subscribe(content => {
|
|
418
625
|
this.currentContent = content;
|
|
419
626
|
if (content) {
|
|
@@ -424,8 +631,6 @@ class CollapsibleSidebarComponent {
|
|
|
424
631
|
}
|
|
425
632
|
this.cdr.markForCheck();
|
|
426
633
|
});
|
|
427
|
-
}
|
|
428
|
-
ngAfterViewInit() {
|
|
429
634
|
// Double rAF: wait until after layout so we do not trigger transitions from mount → closed.
|
|
430
635
|
requestAnimationFrame(() => {
|
|
431
636
|
requestAnimationFrame(() => {
|
|
@@ -610,7 +815,7 @@ class HeaderComponent extends AppBaseComponent {
|
|
|
610
815
|
this.isMenuCollapsed = !this.isMenuCollapsed;
|
|
611
816
|
}
|
|
612
817
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HeaderComponent, deps: [{ token: i0.Injector }, { token: i1.AuthService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
613
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HeaderComponent, isStandalone: false, selector: "pw-header", inputs: { landing: "landing" }, usesInheritance: true, ngImport: i0, template: "<div class=\"navbar navbar-expand-lg fixed-top-nav fixed-top\"\n [ngClass]=\"{ 'navbar-blue': !landing }\">\n <div class=\"container d-block\">\n <div class=\"row m-0\">\n <div class=\"col-lg-2 float-start\">\n <a href=\"/\">\n <img [src]=\"logo\"\n class=\"header-logo\"\n alt=\"site-logo\" />\n </a>\n <button type=\"button\"\n class=\"navbar-toggle\"\n (click)=\"toggleMenu()\"\n [attr.aria-expanded]=\"!isMenuCollapsed\">\n <span class=\"icon-bar\"></span> <span class=\"icon-bar\"></span>\n <span class=\"icon-bar\"></span>\n </button>\n </div>\n <div class=\"col-lg-10 nav-outer mt-2\">\n <div class=\"navbar-collapse float-end\"\n [class.collapse]=\"isMenuCollapsed\"\n [class.show]=\"!isMenuCollapsed\"\n id=\"myNavbar\">\n <nav class=\"navbar navbar-expand-sm bg-light\">\n <ul class=\"navbar-nav\">\n <li class=\"nav-item contact-button\">\n <a href=\"/\"\n class=\"\">{{ 'Button.Home' | transloco }}</a>\n </li>\n @if (!loggedIn) {\n <li class=\"nav-item login-button\">\n <a class=\"\"\n (click)=\"navigateToLogin()\"> log in</a>\n </li>\n }\n </ul>\n </nav>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.navbar-blue{background-color:var(--first);box-shadow:2px 2px 15px 2px #0000001f;transition:width 2s,height 2s,transform 2s background-color .5s ease;z-index:9999}.fixed-top-nav{display:block!important;height:60px}.navbar-toggle{display:none}.navbar-toggle .icon-bar{color:#fff}.nav-outer{text-align:right}.nav-outer nav{background:none!important;display:inline-block;float:none;width:auto}.nav-outer li a{color:#fff;font-size:18px;margin:0 0 0 30px;text-transform:capitalize}.nav-outer li a:hover{color:#fff;text-decoration:none}.nav-outer li a:focus{color:#fff}.navbar-nav li{display:inline-block}@media screen and (max-width:1199px){.nav-outer li a{margin:0 10px}}@media screen and (max-width:991px){.icon-bar{background-color:#fff;border-radius:1px;display:block;height:2px;margin-top:4px;width:22px}.navbar-toggle{background-color:#ffb92b!important;background-image:none;border:1px solid rgb(255,255,255);border-radius:4px;display:block!important;float:right;margin-top:4px;padding:9px 10px;position:relative}.collapse{display:none!important}.collapse.show{display:block!important}.nav-outer nav{background:#ffb92b!important;display:inline-block;float:left;padding:20px;width:100%}.nav-outer li a{margin:0;padding:0}.navbar-expand-sm,.navbar-nav{-webkit-box-direction:normal;-webkit-box-orient:horizontal;flex-direction:column}li.nav-item{float:left;margin-bottom:12px;text-align:left;width:100%}.navbar-expand-sm{-webkit-box-direction:normal;-webkit-box-orient:horizontal;-webkit-box-pack:start;flex-flow:column nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{left:auto;right:0}.nav-outer li a:hover{color:#0a56d3}.contact-button a,.login-button a,.nav-item{background:none;color:#fff!important;font-weight:600}.contact-button a:hover,.login-button a:hover,.nav-item a:hover{color:#0a56d3!important}}@media screen and (max-width:767px){.fixed-top{padding:10px;top:0!important}}@media screen and (max-width:575px){.fixed-top{padding:10px;top:0!important}}@media screen and (max-width:375px){.navbar .container{padding:0!important}}@media(min-width:641px)and (max-width:991px){.navbar-toggle{margin-top:6px}}.header-logo{height:auto!important;width:auto;max-height:40px;max-width:100%;object-fit:contain}.login-button a{background-color:var(--second);color:#fff}.login-button a:hover{background-color:#fff;color:var(--second)!important}.contact-button a{background-color:var(--third);color:#fff}.contact-button a:hover{background-color:#fff;color:var(--third)!important}.fixed-top{position:fixed!important}\n"], dependencies: [{ kind: "directive", type: i3.LazyImgDirective, selector: "img" }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
|
|
818
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: HeaderComponent, isStandalone: false, selector: "pw-header", inputs: { landing: "landing" }, usesInheritance: true, ngImport: i0, template: "<div class=\"navbar navbar-expand-lg fixed-top-nav fixed-top\"\n [ngClass]=\"{ 'navbar-blue': !landing }\">\n <div class=\"container d-block\">\n <div class=\"row m-0\">\n <div class=\"col-lg-2 float-start\">\n <a href=\"/\">\n <img [src]=\"logo\"\n class=\"header-logo\"\n alt=\"site-logo\" />\n </a>\n <button type=\"button\"\n class=\"navbar-toggle\"\n (click)=\"toggleMenu()\"\n [attr.aria-expanded]=\"!isMenuCollapsed\">\n <span class=\"icon-bar\"></span> <span class=\"icon-bar\"></span>\n <span class=\"icon-bar\"></span>\n </button>\n </div>\n <div class=\"col-lg-10 nav-outer mt-2\">\n <div class=\"navbar-collapse float-end\"\n [class.collapse]=\"isMenuCollapsed\"\n [class.show]=\"!isMenuCollapsed\"\n id=\"myNavbar\">\n <nav class=\"navbar navbar-expand-sm bg-light\">\n <ul class=\"navbar-nav\">\n <li class=\"nav-item contact-button\">\n <a href=\"/\"\n class=\"\">{{ 'Button.Home' | transloco }}</a>\n </li>\n @if (!loggedIn) {\n <li class=\"nav-item login-button\">\n <a class=\"\"\n (click)=\"navigateToLogin()\"> log in</a>\n </li>\n }\n </ul>\n </nav>\n </div>\n </div>\n </div>\n </div>\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.navbar-blue{background-color:var(--first);box-shadow:2px 2px 15px 2px #0000001f;transition:width 2s,height 2s,transform 2s background-color .5s ease;z-index:9999}.fixed-top-nav{display:block!important;height:60px}.navbar-toggle{display:none}.navbar-toggle .icon-bar{color:#fff}.nav-outer{text-align:right}.nav-outer nav{background:none!important;display:inline-block;float:none;width:auto}.nav-outer li a{color:#fff;font-size:18px;margin:0 0 0 30px;text-transform:capitalize}.nav-outer li a:hover{color:#fff;text-decoration:none}.nav-outer li a:focus{color:#fff}.navbar-nav li{display:inline-block}@media screen and (max-width:1199px){.nav-outer li a{margin:0 10px}}@media screen and (max-width:991px){.icon-bar{background-color:#fff;border-radius:1px;display:block;height:2px;margin-top:4px;width:22px}.navbar-toggle{background-color:#ffb92b!important;background-image:none;border:1px solid rgb(255,255,255);border-radius:4px;display:block!important;float:right;margin-top:4px;padding:9px 10px;position:relative}.collapse{display:none!important}.collapse.show{display:block!important}.nav-outer nav{background:#ffb92b!important;display:inline-block;float:left;padding:20px;width:100%}.nav-outer li a{margin:0;padding:0}.navbar-expand-sm,.navbar-nav{-webkit-box-direction:normal;-webkit-box-orient:horizontal;flex-direction:column}li.nav-item{float:left;margin-bottom:12px;text-align:left;width:100%}.navbar-expand-sm{-webkit-box-direction:normal;-webkit-box-orient:horizontal;-webkit-box-pack:start;flex-flow:column nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{left:auto;right:0}.nav-outer li a:hover{color:#0a56d3}.contact-button a,.login-button a,.nav-item{background:none;color:#fff!important;font-weight:600}.contact-button a:hover,.login-button a:hover,.nav-item a:hover{color:#0a56d3!important}}@media screen and (max-width:767px){.fixed-top{padding:10px;top:0!important}}@media screen and (max-width:575px){.fixed-top{padding:10px;top:0!important}}@media screen and (max-width:375px){.navbar .container{padding:0!important}}@media(min-width:641px)and (max-width:991px){.navbar-toggle{margin-top:6px}}.header-logo{height:auto!important;width:auto;max-height:40px;max-width:100%;object-fit:contain}.login-button a{background-color:var(--second);color:#fff}.login-button a:hover{background-color:#fff;color:var(--second)!important}.contact-button a{background-color:var(--third);color:#fff}.contact-button a:hover{background-color:#fff;color:var(--third)!important}.fixed-top{position:fixed!important}\n"], dependencies: [{ kind: "directive", type: i3$1.LazyImgDirective, selector: "img" }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
|
|
614
819
|
}
|
|
615
820
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: HeaderComponent, decorators: [{
|
|
616
821
|
type: Component,
|
|
@@ -655,7 +860,7 @@ class NoDataComponent {
|
|
|
655
860
|
}
|
|
656
861
|
<ng-content></ng-content>
|
|
657
862
|
</div>
|
|
658
|
-
`, isInline: true, styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.no-data{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%;border:1px dashed rgb(204,204,204);border-radius:4px;margin:20px 0;padding:10px;background:#fafafa!important;color:oklch(from var(--text) 40% c h)!important}.no-data .message{font-weight:600;font-size:15px;color:oklch(from var(--text) 40% c h)!important}.no-data.has-content{padding-top:10px;padding-bottom:20px}.no-data .nothing-found-image{margin-top:15px;height:auto;max-width:150px}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.LazyImgDirective, selector: "img" }] }); }
|
|
863
|
+
`, isInline: true, styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.no-data{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;width:100%;height:100%;border:1px dashed rgb(204,204,204);border-radius:4px;margin:20px 0;padding:10px;background:#fafafa!important;color:oklch(from var(--text) 40% c h)!important}.no-data .message{font-weight:600;font-size:15px;color:oklch(from var(--text) 40% c h)!important}.no-data.has-content{padding-top:10px;padding-bottom:20px}.no-data .nothing-found-image{margin-top:15px;height:auto;max-width:150px}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$1.LazyImgDirective, selector: "img" }] }); }
|
|
659
864
|
}
|
|
660
865
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: NoDataComponent, decorators: [{
|
|
661
866
|
type: Component,
|
|
@@ -829,13 +1034,13 @@ class EntityGroupComponent extends AppBaseComponent {
|
|
|
829
1034
|
ngOnDestroy() {
|
|
830
1035
|
super.ngOnDestroy();
|
|
831
1036
|
}
|
|
832
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EntityGroupComponent, deps: [{ token: i1.GroupService }, { token: i1.SubscriptionService }, { token: i3$
|
|
833
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: EntityGroupComponent, isStandalone: false, selector: "pw-entity-group", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Team View</h2>\n\n <p>\n In this section, based on your permissions, you can add/remove members from your\n teams.\n <br />\n Then, you'll be able to see powerful insight on the activities performed by your\n team's members.\n </p>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 col-xs-12 d-flex align-items-sm-center align-items-top text-start pe-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"ms-sm-2 d-inline mt-0 card-title mb-3 mb-sm-0\">\n Team view: {{ selectedGroup?.name }}\n </h3>\n </div>\n <div class=\"col-md-6 col-xs-12 text-end justify-content-end\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"open()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-2\"\n (click)=\"navigateToCommunications()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> See Communications\n </button>\n }\n </div>\n </div>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n <div class=\"primeng-datatable-container table-responsive\"\n [class.hideTable]=\"subscribedMembers?.length === 0\">\n <p-table #dt\n [value]=\"subscribedMembers\"\n [paginator]=\"true\"\n [rows]=\"PAGE_SIZE\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\">{{ 'Label.FirstName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.LastName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\"\n let-member>\n <tr class=\"table-row\">\n <td data-head=\"First Name\">\n <a [routerLink]=\"['/members', member.slug]\">{{ member.first_name || null }}\n </a>\n </td>\n <td data-head=\"Last Name\">{{ member.last_name || null }}</td>\n <td data-head=\"Email\">{{ member.email }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (member.id !== userId) {\n <li ngbTooltip=\"Message\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"member.slug\">\n <i\n class=\"fa fa-comments cta1-icon\"\n *rbacAllow=\"chatPermission\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n @if (hasAccess) {\n <li ngbTooltip=\"Remove\"\n class=\"me-2 me-sm-3\"\n (click)=\"onDelete(member.id)\"\n (keydown.enter)=\"onDelete(member.id)\"\n (keydown.space)=\"onDelete(member.id)\"\n >\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n @if (subscribedMembers?.length === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"There are no members in this team yet.\"\n >\n </pw-no-data>\n }\n </div>\n\n <ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add Members</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Please start typing to select the members to add to this team.</p>\n <div class=\"ui-fluid skills-modal\">\n <p-autoComplete [suggestions]=\"filteredMembers\"\n [(ngModel)]=\"selectedMembers\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n placeholder=\"Member\"\n [multiple]=\"true\">\n </p-autoComplete>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"closeModal(modal)\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"onSave()\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </ng-template>\n", styles: ["a.previous i{line-height:23px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.RbacAllowDirective, selector: "[rbacAllow]", inputs: ["rbacAllow"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i3$1.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i6.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i7$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i9.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
|
|
1037
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EntityGroupComponent, deps: [{ token: i1.GroupService }, { token: i1.SubscriptionService }, { token: i3$2.NgbModal }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1038
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: EntityGroupComponent, isStandalone: false, selector: "pw-entity-group", viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Team View</h2>\n\n <p>\n In this section, based on your permissions, you can add/remove members from your\n teams.\n <br />\n Then, you'll be able to see powerful insight on the activities performed by your\n team's members.\n </p>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 col-xs-12 d-flex align-items-sm-center align-items-top text-start pe-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"ms-sm-2 d-inline mt-0 card-title mb-3 mb-sm-0\">\n Team view: {{ selectedGroup?.name }}\n </h3>\n </div>\n <div class=\"col-md-6 col-xs-12 text-end justify-content-end\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"open()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-2\"\n (click)=\"navigateToCommunications()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> See Communications\n </button>\n }\n </div>\n </div>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n <div class=\"primeng-datatable-container table-responsive\"\n [class.hideTable]=\"subscribedMembers?.length === 0\">\n <p-table #dt\n [value]=\"subscribedMembers\"\n [paginator]=\"true\"\n [rows]=\"PAGE_SIZE\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\">{{ 'Label.FirstName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.LastName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\"\n let-member>\n <tr class=\"table-row\">\n <td data-head=\"First Name\">\n <a [routerLink]=\"['/members', member.slug]\">{{ member.first_name || null }}\n </a>\n </td>\n <td data-head=\"Last Name\">{{ member.last_name || null }}</td>\n <td data-head=\"Email\">{{ member.email }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (member.id !== userId) {\n <li ngbTooltip=\"Message\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"member.slug\">\n <i\n class=\"fa fa-comments cta1-icon\"\n *rbacAllow=\"chatPermission\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n @if (hasAccess) {\n <li ngbTooltip=\"Remove\"\n class=\"me-2 me-sm-3\"\n (click)=\"onDelete(member.id)\"\n (keydown.enter)=\"onDelete(member.id)\"\n (keydown.space)=\"onDelete(member.id)\"\n >\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n @if (subscribedMembers?.length === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"There are no members in this team yet.\"\n >\n </pw-no-data>\n }\n </div>\n\n <ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add Members</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Please start typing to select the members to add to this team.</p>\n <div class=\"ui-fluid skills-modal\">\n <p-autoComplete [suggestions]=\"filteredMembers\"\n [(ngModel)]=\"selectedMembers\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n placeholder=\"Member\"\n [multiple]=\"true\">\n </p-autoComplete>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"closeModal(modal)\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"onSave()\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </ng-template>\n", styles: ["a.previous i{line-height:23px}\n"], dependencies: [{ kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$1.RbacAllowDirective, selector: "[rbacAllow]", inputs: ["rbacAllow"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i3$2.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i6.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i7$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i9.AutoComplete, selector: "p-autoComplete, p-autocomplete, p-auto-complete", inputs: ["minLength", "minQueryLength", "delay", "panelStyle", "styleClass", "panelStyleClass", "inputStyle", "inputId", "inputStyleClass", "placeholder", "readonly", "scrollHeight", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "autoHighlight", "forceSelection", "type", "autoZIndex", "baseZIndex", "ariaLabel", "dropdownAriaLabel", "ariaLabelledBy", "dropdownIcon", "unique", "group", "completeOnFocus", "showClear", "dropdown", "showEmptyMessage", "dropdownMode", "multiple", "addOnTab", "tabindex", "dataKey", "emptyMessage", "showTransitionOptions", "hideTransitionOptions", "autofocus", "autocomplete", "optionGroupChildren", "optionGroupLabel", "overlayOptions", "suggestions", "optionLabel", "optionValue", "id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "selectOnFocus", "searchLocale", "optionDisabled", "focusOnHover", "typeahead", "addOnBlur", "separator", "appendTo", "motionOptions"], outputs: ["completeMethod", "onSelect", "onUnselect", "onAdd", "onFocus", "onBlur", "onDropdownClick", "onClear", "onInputKeydown", "onKeyUp", "onShow", "onHide", "onLazyLoad"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
|
|
834
1039
|
}
|
|
835
1040
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: EntityGroupComponent, decorators: [{
|
|
836
1041
|
type: Component,
|
|
837
1042
|
args: [{ selector: 'pw-entity-group', standalone: false, template: "<div>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Team View</h2>\n\n <p>\n In this section, based on your permissions, you can add/remove members from your\n teams.\n <br />\n Then, you'll be able to see powerful insight on the activities performed by your\n team's members.\n </p>\n </div>\n </div>\n\n <div class=\"row\">\n <div class=\"col-md-6 col-xs-12 d-flex align-items-sm-center align-items-top text-start pe-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"ms-sm-2 d-inline mt-0 card-title mb-3 mb-sm-0\">\n Team view: {{ selectedGroup?.name }}\n </h3>\n </div>\n <div class=\"col-md-6 col-xs-12 text-end justify-content-end\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"open()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Members\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-2\"\n (click)=\"navigateToCommunications()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> See Communications\n </button>\n }\n </div>\n </div>\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n <div class=\"primeng-datatable-container table-responsive\"\n [class.hideTable]=\"subscribedMembers?.length === 0\">\n <p-table #dt\n [value]=\"subscribedMembers\"\n [paginator]=\"true\"\n [rows]=\"PAGE_SIZE\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th scope=\"true\">{{ 'Label.FirstName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.LastName' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Email' | transloco }}</th>\n <th scope=\"true\">{{ 'Label.Actions' | transloco }}</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\"\n let-member>\n <tr class=\"table-row\">\n <td data-head=\"First Name\">\n <a [routerLink]=\"['/members', member.slug]\">{{ member.first_name || null }}\n </a>\n </td>\n <td data-head=\"Last Name\">{{ member.last_name || null }}</td>\n <td data-head=\"Email\">{{ member.email }}</td>\n <td data-head=\"Action\">\n <ul class=\"list-unstyled list-inline list-action\">\n @if (member.id !== userId) {\n <li ngbTooltip=\"Message\"\n class=\"me-2 me-sm-3\"\n [routerLink]=\"['/message']\"\n [fragment]=\"member.slug\">\n <i\n class=\"fa fa-comments cta1-icon\"\n *rbacAllow=\"chatPermission\"\n aria-hidden=\"true\"\n ></i>\n </li>\n }\n @if (hasAccess) {\n <li ngbTooltip=\"Remove\"\n class=\"me-2 me-sm-3\"\n (click)=\"onDelete(member.id)\"\n (keydown.enter)=\"onDelete(member.id)\"\n (keydown.space)=\"onDelete(member.id)\"\n >\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i>\n </li>\n }\n </ul>\n </td>\n </tr>\n </ng-template>\n </p-table>\n </div>\n @if (subscribedMembers?.length === 0 && isLoaded) {\n <pw-no-data [withImage]=\"true\" message=\"There are no members in this team yet.\"\n >\n </pw-no-data>\n }\n </div>\n\n <ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h4 class=\"modal-title\"\n id=\"modal-basic-title\">Add Members</h4>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n\n </button>\n </div>\n <div class=\"modal-body\">\n <p>Please start typing to select the members to add to this team.</p>\n <div class=\"ui-fluid skills-modal\">\n <p-autoComplete [suggestions]=\"filteredMembers\"\n [(ngModel)]=\"selectedMembers\"\n dataKey=\"id\"\n optionLabel=\"displayName\"\n (completeMethod)=\"search($event)\"\n styleClass=\"w-100\"\n placeholder=\"Member\"\n [multiple]=\"true\">\n </p-autoComplete>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button type=\"button\"\n class=\"btn btn-outline-default\"\n (click)=\"closeModal(modal)\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"button\"\n class=\"btn btn-primary\"\n (click)=\"onSave()\">\n {{ 'Button.Save' | transloco }}\n </button>\n </div>\n </ng-template>\n", styles: ["a.previous i{line-height:23px}\n"] }]
|
|
838
|
-
}], ctorParameters: () => [{ type: i1.GroupService }, { type: i1.SubscriptionService }, { type: i3$
|
|
1043
|
+
}], ctorParameters: () => [{ type: i1.GroupService }, { type: i1.SubscriptionService }, { type: i3$2.NgbModal }, { type: i0.Injector }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
|
|
839
1044
|
type: ViewChild,
|
|
840
1045
|
args: ['content', { static: true }]
|
|
841
1046
|
}] } });
|
|
@@ -1001,7 +1206,7 @@ class GroupDefinitionComponent extends AppBaseComponent {
|
|
|
1001
1206
|
super.ngOnDestroy();
|
|
1002
1207
|
}
|
|
1003
1208
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GroupDefinitionComponent, deps: [{ token: i1.GroupService }, { token: i2$1.UntypedFormBuilder }, { token: i1.SubscriptionService }, { token: i1.DataService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1004
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: GroupDefinitionComponent, isStandalone: false, selector: "pw-group-definition", usesInheritance: true, ngImport: i0, template: "<section>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Enterprise Teams Categories</h2>\n\n <p>\n Here you can define the categories for your enterprise's groups. For example \"Sales\n Department\", \"Development Department\", etc.\n <br />\n Once the category created, you'll be able to add teams to them and see useful\n insight based on the members activity in the corresponding team.\n </p>\n </div>\n </div>\n\n @if (!viewDefinition) {\n <div class=\"row\"\n >\n <div class=\"col-6 d-flex align-items-center text-start mb-sm-3 mb-lg-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"previous()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n </div>\n @if (hasAccess) {\n <div class=\"col-6\"\n >\n <button class=\"float-end btn btn-sm btn-outline-primary me-2\"\n (click)=\"viewDefinitions()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Create Team Category\n </button>\n </div>\n }\n </div>\n }\n\n @if (viewDefinition) {\n <div>\n <h4 class=\"card-title d-inline mb-5\">\n {{ viewEdit ? 'Update the' : 'Create a new' }} category\n </h4>\n @if (!viewEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"saveGroupDefinition()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-name-label\" class=\"pw-label-style\">{{ 'Label.Name' | transloco }}</span>\n <input type=\"text\"\n id=\"group-definition-name\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'group-definition-name-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}</span>\n <input type=\"text\"\n id=\"group-definition-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'group-definition-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-is_private-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.IsPrivate' | transloco }}</span>\n <div class=\"display-block\">\n <ui-switch size=\"small\"\n [attr.aria-labelledby]=\"'group-definition-is_private-label'\"\n checkedLabel=\"True\"\n uncheckedLabel=\"false\"\n formControlName=\"is_private\">\n </ui-switch>\n </div>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"categoryBusyButton\"\n class=\"btn btn-primary\">Add Category</button>\n </div>\n </div>\n </form>\n </div>\n }\n @if (viewEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"updateDetails()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-name-label\" class=\"pw-label-style\">{{ 'Label.Name' | transloco }}: </span>\n <input type=\"text\"\n id=\"group-definition-edit-name\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'group-definition-edit-name-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}:</span>\n <input type=\"text\"\n id=\"group-definition-edit-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'group-definition-edit-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-is_private-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.IsPrivate' | transloco }}</span>\n <div class=\"display-block\">\n <ui-switch size=\"small\"\n [attr.aria-labelledby]=\"'group-definition-edit-is_private-label'\"\n checkedLabel=\"True\"\n uncheckedLabel=\"false\"\n formControlName=\"is_private\">\n </ui-switch>\n </div>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"categoryBusyButton\"\n class=\"btn btn-primary\">\n {{ 'Button.Update' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n }\n </div>\n }\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if (groupDefinition?.length !== 0) {\n @if (!viewDefinition) {\n <div class=\"row mb-last-3 group-definitions-wrapper\"\n >\n @for (group of groupDefinition; track group) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3\"\n >\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h5 class=\"mb-3\">{{ group.name }}</h5>\n <p>{{ group.description | slice: 0:200 }}</p>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (hasAccess) {\n <a class=\"btn btn-sm btn-outline-danger me-2\"\n (click)=\"onDelete(group.id)\">{{ 'Button.Delete' | transloco }}</a>\n }\n @if (hasAccess) {\n <a class=\"btn btn-sm btn-outline-primary me-2\"\n (click)=\"onGroupDefinitionEdit(group.id)\">{{ 'Button.Edit' | transloco }}</a>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n }\n @if (groupDefinition?.length === 0 && hasAccess && !viewDefinition && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoLabelsMessage' | transloco\"> </pw-no-data>\n </div>\n }\n @if (groupDefinition?.length === 0 && !hasAccess && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoLabelsUserMessage' | transloco\"> </pw-no-data>\n </div>\n }\n </section>\n", styles: [".mb-last-3{margin-bottom:3rem}\n"], dependencies: [{ kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i5.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i7.SlicePipe, name: "slice" }] }); }
|
|
1209
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: GroupDefinitionComponent, isStandalone: false, selector: "pw-group-definition", usesInheritance: true, ngImport: i0, template: "<section>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Enterprise Teams Categories</h2>\n\n <p>\n Here you can define the categories for your enterprise's groups. For example \"Sales\n Department\", \"Development Department\", etc.\n <br />\n Once the category created, you'll be able to add teams to them and see useful\n insight based on the members activity in the corresponding team.\n </p>\n </div>\n </div>\n\n @if (!viewDefinition) {\n <div class=\"row\"\n >\n <div class=\"col-6 d-flex align-items-center text-start mb-sm-3 mb-lg-0\">\n <a aria-label=\"Navigate to Target\"\n (click)=\"previous()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n </div>\n @if (hasAccess) {\n <div class=\"col-6\"\n >\n <button class=\"float-end btn btn-sm btn-outline-primary me-2\"\n (click)=\"viewDefinitions()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Create Team Category\n </button>\n </div>\n }\n </div>\n }\n\n @if (viewDefinition) {\n <div>\n <h4 class=\"card-title d-inline mb-5\">\n {{ viewEdit ? 'Update the' : 'Create a new' }} category\n </h4>\n @if (!viewEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"saveGroupDefinition()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-name-label\" class=\"pw-label-style\">{{ 'Label.Name' | transloco }}</span>\n <input type=\"text\"\n id=\"group-definition-name\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'group-definition-name-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}</span>\n <input type=\"text\"\n id=\"group-definition-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'group-definition-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-is_private-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.IsPrivate' | transloco }}</span>\n <div class=\"display-block\">\n <ui-switch size=\"small\"\n [attr.aria-labelledby]=\"'group-definition-is_private-label'\"\n checkedLabel=\"True\"\n uncheckedLabel=\"false\"\n formControlName=\"is_private\">\n </ui-switch>\n </div>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"categoryBusyButton\"\n class=\"btn btn-primary\">Add Category</button>\n </div>\n </div>\n </form>\n </div>\n }\n @if (viewEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"updateDetails()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-name-label\" class=\"pw-label-style\">{{ 'Label.Name' | transloco }}: </span>\n <input type=\"text\"\n id=\"group-definition-edit-name\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'group-definition-edit-name-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}:</span>\n <input type=\"text\"\n id=\"group-definition-edit-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'group-definition-edit-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"group-definition-edit-is_private-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.IsPrivate' | transloco }}</span>\n <div class=\"display-block\">\n <ui-switch size=\"small\"\n [attr.aria-labelledby]=\"'group-definition-edit-is_private-label'\"\n checkedLabel=\"True\"\n uncheckedLabel=\"false\"\n formControlName=\"is_private\">\n </ui-switch>\n </div>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"onCancel()\"\n (keydown.enter)=\"onCancel()\" >\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"categoryBusyButton\"\n class=\"btn btn-primary\">\n {{ 'Button.Update' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n }\n </div>\n }\n\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n\n @if (groupDefinition?.length !== 0) {\n @if (!viewDefinition) {\n <div class=\"row mb-last-3 group-definitions-wrapper\"\n >\n @for (group of groupDefinition; track group) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3\"\n >\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h5 class=\"mb-3\">{{ group.name }}</h5>\n <p>{{ group.description | slice: 0:200 }}</p>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (hasAccess) {\n <a class=\"btn btn-sm btn-outline-danger me-2\"\n (click)=\"onDelete(group.id)\">{{ 'Button.Delete' | transloco }}</a>\n }\n @if (hasAccess) {\n <a class=\"btn btn-sm btn-outline-primary me-2\"\n (click)=\"onGroupDefinitionEdit(group.id)\">{{ 'Button.Edit' | transloco }}</a>\n }\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n }\n @if (groupDefinition?.length === 0 && hasAccess && !viewDefinition && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoLabelsMessage' | transloco\"> </pw-no-data>\n </div>\n }\n @if (groupDefinition?.length === 0 && !hasAccess && isLoaded) {\n <div>\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoLabelsUserMessage' | transloco\"> </pw-no-data>\n </div>\n }\n </section>\n", styles: [".mb-last-3{margin-bottom:3rem}\n"], dependencies: [{ kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3$1.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "component", type: i5.UiSwitchComponent, selector: "ui-switch", inputs: ["size", "color", "switchOffColor", "switchColor", "defaultBgColor", "defaultBoColor", "checkedLabel", "uncheckedLabel", "checkedTextColor", "uncheckedTextColor", "beforeChange", "ariaLabel", "checked", "disabled", "reverse", "loading"], outputs: ["change", "changeEvent", "valueChange"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i7.SlicePipe, name: "slice" }] }); }
|
|
1005
1210
|
}
|
|
1006
1211
|
__decorate([
|
|
1007
1212
|
ValidateForm('form'),
|
|
@@ -1233,7 +1438,7 @@ class GroupsComponent extends AppBaseComponent {
|
|
|
1233
1438
|
super.ngOnDestroy();
|
|
1234
1439
|
}
|
|
1235
1440
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GroupsComponent, deps: [{ token: i2$1.UntypedFormBuilder }, { token: i1.GroupService }, { token: i1.SubscriptionService }, { token: i1.DataService }, { token: i0.Injector }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1236
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: GroupsComponent, isStandalone: false, selector: "pw-groups", usesInheritance: true, ngImport: i0, template: "<div>\n <section>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Enterprise Teams</h2>\n\n <p>\n Here you can define the teams for your Enterprise members. For example\n \"Corporate Sales Team\", \"Frontend Dev Team\" etc.\n <br />\n Once the teams created, you'll be able to add members to them and see useful\n insight based on the members activity in the corresponding team.\n </p>\n </div>\n </div>\n\n @if (!isGroupOperations) {\n <div class=\"row\"\n >\n <div class=\"col-12 d-flex justify-content-end align-items-center text-end mb-3\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"groupOperation()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Team\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-1\"\n [routerLink]=\"['/' + subscription?.slug + '/enterprise', 'groups', 'labels']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Manage Team Categories\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Add Group Template -->\n @if (isGroupOperations) {\n <div\n class=\"mb-4\">\n <h4 class=\"card-title d-inline\">{{ viewEdit ? 'Update the' : 'Create a new' }} team</h4>\n @if (!isGroupEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"saveGroup()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-teamName-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamName' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-teamName\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'groups-teamName-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'groups-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-teamCategory-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamCategory' | transloco\n }}<span class=\"text-danger required-icon\">*</span>\n </span>\n <p-select\n [attr.aria-labelledby]=\"'groups-teamCategory-label'\"\n [options]=\"groupDefinition\"\n formControlName=\"group_definition_id\"\n [ngClass]=\"{'is-invalid': submitted && form.controls['group_definition_id'].errors}\"\n [placeholder]=\"'Select Team Category'\"\n optionValue=\"id\"\n optionLabel=\"name\">\n </p-select>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n (click)=\"isGroupOperations = !isGroupOperations\"\n class=\"btn btn-outline-default me-2\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">Add</button>\n </div>\n </div>\n </form>\n </div>\n }\n <!-- Edit Group Template -->\n @if (isGroupEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"updateDetails()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-teamName-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamName' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-edit-teamName\"\n class=\"form-control\"\n formControlName=\"name\"\n required=\"true\"\n [attr.aria-labelledby]=\"'groups-edit-teamName-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamDescription' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-edit-description\"\n value=\"{{ description }}\"\n class=\"form-control\"\n formControlName=\"description\"\n required=\"true\"\n [attr.aria-labelledby]=\"'groups-edit-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-teamCategory-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamCategory' | transloco\n }}<span class=\"text-danger required-icon\">*</span>\n </span>\n <p-select\n [attr.aria-labelledby]=\"'groups-edit-teamCategory-label'\"\n [options]=\"groupDefinition\"\n formControlName=\"group_definition_id\"\n [ngClass]=\"{'is-invalid': submitted && form.controls['group_definition_id'].errors}\"\n [placeholder]=\"'Select Team Category'\"\n optionValue=\"id\"\n optionLabel=\"name\">\n </p-select>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"cancelUpdate()\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">\n {{ 'Button.Update' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n }\n </div>\n }\n\n @if (!isGroupOperations) {\n <div class=\"row\"\n >\n <div class=\"col-4 mt-2 filter\">\n <p-select\n [options]=\"domainGroupDefinition\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [ngModel]=\"'0'\"\n (onChange)=\"filterDomainsList($event.value)\">\n </p-select>\n </div>\n </div>\n }\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (!isGroupOperations) {\n <div class=\"row group_list my-4\"\n >\n @for (group of allGroups; track trackByGroup($index, group)) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3\"\n >\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h5 class=\"mb-3\">{{ group.name }}</h5>\n <p>{{ group.description | slice: 0:200 }}</p>\n <span><a class=\"badge bg-primary\">{{\n group?.group_definition_name\n }}</a></span>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (hasAccess) {\n <a class=\"me-2 my-1\"\n aria-label=\"Delete\"\n (click)=\"onDelete(group.id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i></a>\n }\n @if (hasAccess) {\n <a class=\"me-2 my-1\"\n aria-label=\"Edit Group\"\n (click)=\"editGroup(group.id)\"><i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i></a>\n }\n <a class=\"me-2 my-1\"\n aria-label=\"Members\"\n [routerLink]=\"[group.id, 'members']\"><i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </a>\n <a class=\"communications me-2 my-1\"\n aria-label=\"Communications\"\n (click)=\"navigateToCommunications(group.id)\"><i class=\"fa fa-comments cta2-icon\" aria-hidden=\"true\"></i></a>\n <a class=\"communications my-1\"\n aria-label=\"Documents\"\n (click)=\"navigateToDocumentations(group.id)\"><i class=\"fab fa-wikipedia-w cta1-icon\" aria-hidden=\"true\"></i></a>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </section>\n </div>\n @if (allGroups?.length === 0 && hasAccess && !isGroupOperations && isLoaded) {\n <div\n class=\"clear-both\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoTeamMessage' | transloco\"> </pw-no-data>\n </div>\n }\n @if (allGroups?.length === 0 && !hasAccess && !isGroupOperations && isLoaded) {\n <div\n class=\"clear-both\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoTeamMessageIfUser' | transloco\"> </pw-no-data>\n </div>\n }\n", styles: ["a.previous i{line-height:13px}.clear-both{clear:both}@media screen and (max-width:480px){.filter{flex:none;max-width:100%!important}.communications{margin-top:2%}}\n"], dependencies: [{ kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i5$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i7.SlicePipe, name: "slice" }] }); }
|
|
1441
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: GroupsComponent, isStandalone: false, selector: "pw-groups", usesInheritance: true, ngImport: i0, template: "<div>\n <section>\n <div class=\"row\">\n <div class=\"col-12 mb-3\">\n <h2>Enterprise Teams</h2>\n\n <p>\n Here you can define the teams for your Enterprise members. For example\n \"Corporate Sales Team\", \"Frontend Dev Team\" etc.\n <br />\n Once the teams created, you'll be able to add members to them and see useful\n insight based on the members activity in the corresponding team.\n </p>\n </div>\n </div>\n\n @if (!isGroupOperations) {\n <div class=\"row\"\n >\n <div class=\"col-12 d-flex justify-content-end align-items-center text-end mb-3\">\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary\"\n (click)=\"groupOperation()\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Add Team\n </button>\n }\n @if (hasAccess) {\n <button\n class=\"btn btn-sm btn-outline-primary ms-1\"\n [routerLink]=\"['/' + subscription?.slug + '/enterprise', 'groups', 'labels']\">\n <i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i> Manage Team Categories\n </button>\n }\n </div>\n </div>\n }\n\n <!-- Add Group Template -->\n @if (isGroupOperations) {\n <div\n class=\"mb-4\">\n <h4 class=\"card-title d-inline\">{{ viewEdit ? 'Update the' : 'Create a new' }} team</h4>\n @if (!isGroupEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"saveGroup()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-teamName-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamName' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-teamName\"\n class=\"form-control\"\n formControlName=\"name\"\n [attr.aria-labelledby]=\"'groups-teamName-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.Description' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-description\"\n class=\"form-control\"\n formControlName=\"description\"\n [attr.aria-labelledby]=\"'groups-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-teamCategory-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamCategory' | transloco\n }}<span class=\"text-danger required-icon\">*</span>\n </span>\n <p-select\n [attr.aria-labelledby]=\"'groups-teamCategory-label'\"\n [options]=\"groupDefinition\"\n formControlName=\"group_definition_id\"\n [ngClass]=\"{'is-invalid': submitted && form.controls['group_definition_id'].errors}\"\n [placeholder]=\"'Select Team Category'\"\n optionValue=\"id\"\n optionLabel=\"name\">\n </p-select>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n (click)=\"isGroupOperations = !isGroupOperations\"\n class=\"btn btn-outline-default me-2\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">Add</button>\n </div>\n </div>\n </form>\n </div>\n }\n <!-- Edit Group Template -->\n @if (isGroupEdit) {\n <div class=\"mt-4\"\n >\n <form [formGroup]=\"form\"\n (ngSubmit)=\"updateDetails()\">\n <div class=\"row\">\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-teamName-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamName' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-edit-teamName\"\n class=\"form-control\"\n formControlName=\"name\"\n required=\"true\"\n [attr.aria-labelledby]=\"'groups-edit-teamName-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-description-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamDescription' | transloco }}</span>\n <input type=\"text\"\n id=\"groups-edit-description\"\n value=\"{{ description }}\"\n class=\"form-control\"\n formControlName=\"description\"\n required=\"true\"\n [attr.aria-labelledby]=\"'groups-edit-description-label'\" />\n </div>\n <div class=\"mb-3 col-xs-12 col-sm-6 col-md-3\">\n <span id=\"groups-edit-teamCategory-label\" class=\"pw-label-style\">{{ 'Enterprise.Teams.TeamCategory' | transloco\n }}<span class=\"text-danger required-icon\">*</span>\n </span>\n <p-select\n [attr.aria-labelledby]=\"'groups-edit-teamCategory-label'\"\n [options]=\"groupDefinition\"\n formControlName=\"group_definition_id\"\n [ngClass]=\"{'is-invalid': submitted && form.controls['group_definition_id'].errors}\"\n [placeholder]=\"'Select Team Category'\"\n optionValue=\"id\"\n optionLabel=\"name\">\n </p-select>\n </div>\n </div>\n <div class=\"row text-end mt-4\">\n <div class=\"col-12\">\n <button type=\"button\"\n class=\"btn btn-outline-default me-2\"\n (click)=\"cancelUpdate()\">\n {{ 'Button.Cancel' | transloco }}\n </button>\n <button type=\"submit\"\n [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary\">\n {{ 'Button.Update' | transloco }}\n </button>\n </div>\n </div>\n </form>\n </div>\n }\n </div>\n }\n\n @if (!isGroupOperations) {\n <div class=\"row\"\n >\n <div class=\"col-4 mt-2 filter\">\n <p-select\n [options]=\"domainGroupDefinition\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [ngModel]=\"'0'\"\n (onChange)=\"filterDomainsList($event.value)\">\n </p-select>\n </div>\n </div>\n }\n @if (!isLoaded) {\n <div class=\"w-100 text-center mt-3\"\n >\n <p-progressSpinner strokeWidth=\"2\"> </p-progressSpinner>\n </div>\n }\n @if (!isGroupOperations) {\n <div class=\"row group_list my-4\"\n >\n @for (group of allGroups; track trackByGroup($index, group)) {\n <div class=\"col-12 col-md-6 col-xl-4 mt-3\"\n >\n <div class=\"card\">\n <div class=\"card-content\">\n <div class=\"card-header\">\n <h5 class=\"mb-3\">{{ group.name }}</h5>\n <p>{{ group.description | slice: 0:200 }}</p>\n <span><a class=\"badge bg-primary\">{{\n group?.group_definition_name\n }}</a></span>\n </div>\n <div class=\"card-footer\">\n <div class=\"float-end px-2\">\n @if (hasAccess) {\n <a class=\"me-2 my-1\"\n aria-label=\"Delete\"\n (click)=\"onDelete(group.id)\">\n <i class=\"fa fa-trash delete-icon\" aria-hidden=\"true\"></i></a>\n }\n @if (hasAccess) {\n <a class=\"me-2 my-1\"\n aria-label=\"Edit Group\"\n (click)=\"editGroup(group.id)\"><i class=\"fa fa-edit edit-icon\" aria-hidden=\"true\"></i></a>\n }\n <a class=\"me-2 my-1\"\n aria-label=\"Members\"\n [routerLink]=\"[group.id, 'members']\"><i class=\"fa fa-tasks cta1-icon\" aria-hidden=\"true\"></i>\n </a>\n <a class=\"communications me-2 my-1\"\n aria-label=\"Communications\"\n (click)=\"navigateToCommunications(group.id)\"><i class=\"fa fa-comments cta2-icon\" aria-hidden=\"true\"></i></a>\n <a class=\"communications my-1\"\n aria-label=\"Documents\"\n (click)=\"navigateToDocumentations(group.id)\"><i class=\"fab fa-wikipedia-w cta1-icon\" aria-hidden=\"true\"></i></a>\n </div>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </section>\n </div>\n @if (allGroups?.length === 0 && hasAccess && !isGroupOperations && isLoaded) {\n <div\n class=\"clear-both\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoTeamMessage' | transloco\"> </pw-no-data>\n </div>\n }\n @if (allGroups?.length === 0 && !hasAccess && !isGroupOperations && isLoaded) {\n <div\n class=\"clear-both\">\n <pw-no-data [withImage]=\"true\" [message]=\"'Enterprise.Teams.NoTeamMessageIfUser' | transloco\"> </pw-no-data>\n </div>\n }\n", styles: ["a.previous i{line-height:13px}.clear-both{clear:both}@media screen and (max-width:480px){.filter{flex:none;max-width:100%!important}.communications{margin-top:2%}}\n"], dependencies: [{ kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3$1.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "directive", type: i2.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i5$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: NoDataComponent, selector: "pw-no-data", inputs: ["message", "description", "withImage"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }, { kind: "pipe", type: i7.SlicePipe, name: "slice" }] }); }
|
|
1237
1442
|
}
|
|
1238
1443
|
__decorate([
|
|
1239
1444
|
ValidateForm('form'),
|
|
@@ -1508,7 +1713,7 @@ class NumberPickerComponent {
|
|
|
1508
1713
|
this.placeholder = this.placeholder ?? '';
|
|
1509
1714
|
}
|
|
1510
1715
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: NumberPickerComponent, deps: [{ token: i1.NumberPickerService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1511
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: NumberPickerComponent, isStandalone: false, selector: "pw-number-picker", inputs: { min: "min", showTooltip: "showTooltip", tooltipText: "tooltipText", max: "max", step: "step", value: "value", pickStartAfter: "pickStartAfter", pickTimer: "pickTimer", prefix: "prefix", postfix: "postfix", placeholder: "placeholder", buttonsOrientation: "buttonsOrientation", size: "size", customClass: "customClass", mouseWheel: "mouseWheel", arrowKeys: "arrowKeys", inputReadOnly: "inputReadOnly", showUpButton: "showUpButton", showDownButton: "showDownButton", inputId: "inputId" }, outputs: { valueChange: "valueChange", minReached: "minReached", maxReached: "maxReached", pickStarted: "pickStarted", pickStopped: "pickStopped", pickUpStarted: "pickUpStarted", pickUpStopped: "pickUpStopped", pickDownStarted: "pickDownStarted", pickDownStopped: "pickDownStopped" }, ngImport: i0, template: "<div class=\"input-group mb-3 input-{{ size }} {{ customClass.container }}\">\n <!-- Horizontal decrease button orientation -->\n @if (isHorizontal() && showDownButton) {\n <span\n class=\"input-group-text decrease {{ customClass.down }}\"\n (click)=\"onDecrease($event)\"\n (keydown.enter)=\"onDecrease($event)\"\n (mouseup)=\"onMouseUp($event, false)\"\n (mousedown)=\"onMouseDown($event, false)\">-</span>\n }\n <!-- Input prefix -->\n @if (prefix) {\n <span\n class=\"input-group-text {{ customClass.prefix }}\">{{ prefix }}\n </span>\n }\n <input type=\"number\"\n class=\"form-control\"\n [attr.id]=\"inputId\"\n name=\"input-spin-val\"\n [(ngModel)]=\"value\"\n [readOnly]=\"inputReadOnly\"\n (blur)=\"onBlur($event)\"\n (focus)=\"onFocus($event)\"\n (wheel)=\"mouseWheel && onMouseWheel($event)\"\n (keyup)=\"arrowKeys && onKeyUp($event)\"\n (keydown.enter)=\"arrowKeys && onKeyDown($event)\"\n (keydown.arrowup)=\"arrowKeys && onIncrease($event)\"\n (keydown.arrowdown)=\"arrowKeys && onDecrease($event)\"\n (change)=\"onValueChange($event)\"\n [placeholder]=\"placeholder\" />\n <!-- Input postfix -->\n\n @if (postfix) {\n <span\n class=\"input-group-text {{ customClass.postfix }}\"\n [style.borderLeft]=\"'0'\">{{postfix}}\n @if (showTooltip && tooltipText) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-info-circle\"></i>\n </span>\n }\n </span>\n }\n\n <!-- Horizontal increase button orientation -->\n @if (isHorizontal() && showUpButton) {\n <span\n class=\"input-group-text increase {{ customClass.up }}\"\n [style.borderLeft]=\"!postfix ? '0' : ''\"\n (click)=\"onIncrease($event)\"\n (keydown.enter)=\"onIncrease($event)\"\n (mouseup)=\"onMouseUp($event)\"\n (mousedown)=\"onMouseDown($event)\">+</span>\n }\n <!-- Vertical buttons orientation -->\n @if (!isHorizontal()) {\n <span\n class=\"input-group-text vertical p-0\">\n @if (showUpButton) {\n <span\n class=\"{{ customClass.up }}\"\n (click)=\"onIncrease($event)\"\n (keydown.enter)=\"onIncrease($event)\"\n (mouseup)=\"onMouseUp($event)\"\n (mousedown)=\"onMouseDown($event)\">+</span>\n }\n @if (showDownButton) {\n <span\n class=\"{{ customClass.down }}\"\n (keydown.enter)=\"onDecrease($event)\"\n (click)=\"onDecrease($event)\"\n (mouseup)=\"onMouseUp($event, false)\"\n (mousedown)=\"onMouseDown($event, false)\">-</span>\n }\n </span>\n }\n</div>\n", styles: ["input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{appearance:none;margin:0}.increase:hover,.decrease:hover{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;background-color:#d8d8d8}.increase{border-top-right-radius:3px!important;border-bottom-right-radius:3px!important}.vertical{display:flex;justify-content:center;flex-direction:column;text-align:center;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer}.vertical span{line-height:15px}.input-md .vertical span,.input-sm .vertical span{padding:2px 10px}.input-lg .vertical span{padding:4px 10px}.input-xlg .vertical span{padding:7px 10px}.input-md,.input-medium{height:45px}.input-lg,.input-large{height:50px}.input-xlg,.input-xlarge{height:75px}.input-md input,.input-medium input,.input-md span,.input-medium span{font-size:22px}.input-lg input,.input-large input,.input-lg span,.input-large span{font-size:25px}.input-xlg input,.input-xlarge input,.input-xlg span,.input-xlarge span{font-size:38px}\n"], dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$
|
|
1716
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: NumberPickerComponent, isStandalone: false, selector: "pw-number-picker", inputs: { min: "min", showTooltip: "showTooltip", tooltipText: "tooltipText", max: "max", step: "step", value: "value", pickStartAfter: "pickStartAfter", pickTimer: "pickTimer", prefix: "prefix", postfix: "postfix", placeholder: "placeholder", buttonsOrientation: "buttonsOrientation", size: "size", customClass: "customClass", mouseWheel: "mouseWheel", arrowKeys: "arrowKeys", inputReadOnly: "inputReadOnly", showUpButton: "showUpButton", showDownButton: "showDownButton", inputId: "inputId" }, outputs: { valueChange: "valueChange", minReached: "minReached", maxReached: "maxReached", pickStarted: "pickStarted", pickStopped: "pickStopped", pickUpStarted: "pickUpStarted", pickUpStopped: "pickUpStopped", pickDownStarted: "pickDownStarted", pickDownStopped: "pickDownStopped" }, ngImport: i0, template: "<div class=\"input-group mb-3 input-{{ size }} {{ customClass.container }}\">\n <!-- Horizontal decrease button orientation -->\n @if (isHorizontal() && showDownButton) {\n <span\n class=\"input-group-text decrease {{ customClass.down }}\"\n (click)=\"onDecrease($event)\"\n (keydown.enter)=\"onDecrease($event)\"\n (mouseup)=\"onMouseUp($event, false)\"\n (mousedown)=\"onMouseDown($event, false)\">-</span>\n }\n <!-- Input prefix -->\n @if (prefix) {\n <span\n class=\"input-group-text {{ customClass.prefix }}\">{{ prefix }}\n </span>\n }\n <input type=\"number\"\n class=\"form-control\"\n [attr.id]=\"inputId\"\n name=\"input-spin-val\"\n [(ngModel)]=\"value\"\n [readOnly]=\"inputReadOnly\"\n (blur)=\"onBlur($event)\"\n (focus)=\"onFocus($event)\"\n (wheel)=\"mouseWheel && onMouseWheel($event)\"\n (keyup)=\"arrowKeys && onKeyUp($event)\"\n (keydown.enter)=\"arrowKeys && onKeyDown($event)\"\n (keydown.arrowup)=\"arrowKeys && onIncrease($event)\"\n (keydown.arrowdown)=\"arrowKeys && onDecrease($event)\"\n (change)=\"onValueChange($event)\"\n [placeholder]=\"placeholder\" />\n <!-- Input postfix -->\n\n @if (postfix) {\n <span\n class=\"input-group-text {{ customClass.postfix }}\"\n [style.borderLeft]=\"'0'\">{{postfix}}\n @if (showTooltip && tooltipText) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-info-circle\"></i>\n </span>\n }\n </span>\n }\n\n <!-- Horizontal increase button orientation -->\n @if (isHorizontal() && showUpButton) {\n <span\n class=\"input-group-text increase {{ customClass.up }}\"\n [style.borderLeft]=\"!postfix ? '0' : ''\"\n (click)=\"onIncrease($event)\"\n (keydown.enter)=\"onIncrease($event)\"\n (mouseup)=\"onMouseUp($event)\"\n (mousedown)=\"onMouseDown($event)\">+</span>\n }\n <!-- Vertical buttons orientation -->\n @if (!isHorizontal()) {\n <span\n class=\"input-group-text vertical p-0\">\n @if (showUpButton) {\n <span\n class=\"{{ customClass.up }}\"\n (click)=\"onIncrease($event)\"\n (keydown.enter)=\"onIncrease($event)\"\n (mouseup)=\"onMouseUp($event)\"\n (mousedown)=\"onMouseDown($event)\">+</span>\n }\n @if (showDownButton) {\n <span\n class=\"{{ customClass.down }}\"\n (keydown.enter)=\"onDecrease($event)\"\n (click)=\"onDecrease($event)\"\n (mouseup)=\"onMouseUp($event, false)\"\n (mousedown)=\"onMouseDown($event, false)\">-</span>\n }\n </span>\n }\n</div>\n", styles: ["input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{appearance:none;margin:0}.increase:hover,.decrease:hover{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer;background-color:#d8d8d8}.increase{border-top-right-radius:3px!important;border-bottom-right-radius:3px!important}.vertical{display:flex;justify-content:center;flex-direction:column;text-align:center;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;cursor:pointer}.vertical span{line-height:15px}.input-md .vertical span,.input-sm .vertical span{padding:2px 10px}.input-lg .vertical span{padding:4px 10px}.input-xlg .vertical span{padding:7px 10px}.input-md,.input-medium{height:45px}.input-lg,.input-large{height:50px}.input-xlg,.input-xlarge{height:75px}.input-md input,.input-medium input,.input-md span,.input-medium span{font-size:22px}.input-lg input,.input-large input,.input-lg span,.input-large span{font-size:25px}.input-xlg input,.input-xlarge input,.input-xlg span,.input-xlarge span{font-size:38px}\n"], dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] }); }
|
|
1512
1717
|
}
|
|
1513
1718
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: NumberPickerComponent, decorators: [{
|
|
1514
1719
|
type: Component,
|
|
@@ -1607,13 +1812,13 @@ class PasswordValidationComponent extends AppBaseComponent {
|
|
|
1607
1812
|
});
|
|
1608
1813
|
}
|
|
1609
1814
|
}
|
|
1610
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PasswordValidationComponent, deps: [{ token: i0.Injector }, { token: i3$
|
|
1611
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: PasswordValidationComponent, isStandalone: false, selector: "pw-password-validation", inputs: { confirmMessage: "confirmMessage" }, outputs: { successEvent: "successEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Confirm</h5>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"modal-body\">\n <strong class=\"p3\">{{ confirmMessage | transloco }}</strong>\n <div>\n <ng-content></ng-content>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <input type=\"password\"\n #passwordRef\n [(ngModel)]=\"password\"\n class=\"form-control\"\n placeholder=\"Current Password\" id=\"input_password_992\" name=\"input_password_992\" />\n </div>\n </div>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <button [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary float-end\"\n type=\"button\"\n (click)=\"validatePassword()\">\n {{ 'Button.Confirm' | transloco }}\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
|
|
1815
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PasswordValidationComponent, deps: [{ token: i0.Injector }, { token: i3$2.NgbModal }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1816
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.6", type: PasswordValidationComponent, isStandalone: false, selector: "pw-password-validation", inputs: { confirmMessage: "confirmMessage" }, outputs: { successEvent: "successEvent" }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Confirm</h5>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"modal-body\">\n <strong class=\"p3\">{{ confirmMessage | transloco }}</strong>\n <div>\n <ng-content></ng-content>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <input type=\"password\"\n #passwordRef\n [(ngModel)]=\"password\"\n class=\"form-control\"\n placeholder=\"Current Password\" id=\"input_password_992\" name=\"input_password_992\" />\n </div>\n </div>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <button [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary float-end\"\n type=\"button\"\n (click)=\"validatePassword()\">\n {{ 'Button.Confirm' | transloco }}\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3$1.ButtonBusyDirective, selector: "[buttonBusy]", inputs: ["buttonBusy", "busyText"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
|
|
1612
1817
|
}
|
|
1613
1818
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PasswordValidationComponent, decorators: [{
|
|
1614
1819
|
type: Component,
|
|
1615
1820
|
args: [{ selector: 'pw-password-validation', standalone: false, template: "<ng-template #content\n let-modal>\n <div class=\"modal-header\">\n <h5 class=\"modal-title\">Confirm</h5>\n <button type=\"button\"\n class=\"btn-close float-end\"\n aria-label=\"Close\"\n (click)=\"modal.dismiss()\">\n </button>\n </div>\n <div class=\"modal-body\">\n <strong class=\"p3\">{{ confirmMessage | transloco }}</strong>\n <div>\n <ng-content></ng-content>\n </div>\n <div class=\"row\">\n <div class=\"col-12\">\n <input type=\"password\"\n #passwordRef\n [(ngModel)]=\"password\"\n class=\"form-control\"\n placeholder=\"Current Password\" id=\"input_password_992\" name=\"input_password_992\" />\n </div>\n </div>\n <div class=\"row mt-2\">\n <div class=\"col-12\">\n <button [buttonBusy]=\"buttonBusy\"\n class=\"btn btn-primary float-end\"\n type=\"button\"\n (click)=\"validatePassword()\">\n {{ 'Button.Confirm' | transloco }}\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n" }]
|
|
1616
|
-
}], ctorParameters: () => [{ type: i0.Injector }, { type: i3$
|
|
1821
|
+
}], ctorParameters: () => [{ type: i0.Injector }, { type: i3$2.NgbModal }, { type: i0.ChangeDetectorRef }], propDecorators: { content: [{
|
|
1617
1822
|
type: ViewChild,
|
|
1618
1823
|
args: ['content', { static: true }]
|
|
1619
1824
|
}], confirmMessage: [{
|
|
@@ -1654,7 +1859,7 @@ class PermissionTreeComponent {
|
|
|
1654
1859
|
if (!this.data || !this._$tree) {
|
|
1655
1860
|
return;
|
|
1656
1861
|
}
|
|
1657
|
-
const treeData = map(this.data.permissions, item => {
|
|
1862
|
+
const treeData = map$1(this.data.permissions, item => {
|
|
1658
1863
|
return {
|
|
1659
1864
|
id: item.name,
|
|
1660
1865
|
parent: item.parentName ?? '#',
|
|
@@ -1832,7 +2037,7 @@ class PrivacyAndTosComponent extends AppBaseComponent {
|
|
|
1832
2037
|
});
|
|
1833
2038
|
}
|
|
1834
2039
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PrivacyAndTosComponent, deps: [{ token: i1$1.AdminService }, { token: i0.Injector }, { token: DOCUMENT }, { token: i2$2.DomSanitizer }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1835
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: PrivacyAndTosComponent, isStandalone: false, selector: "pw-privacy-and-tos", inputs: { productId: "productId" }, usesInheritance: true, ngImport: i0, template: "@if (isPublic) {\n <pw-header [landing]=\"false\"></pw-header>\n}\n\n@if (!isPublic) {\n <div class=\"col-12 d-flex\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"mt-3\">{{ productName }}</h3>\n </div>\n }\n\n\n\n\n <div [ngClass]=\"{ 'container pw-tab overflow-hidden': isPublic }\" >\n <div [ngClass]=\"{ dashboard: isPublic }\">\n <div [ngClass]=\"{ 'dashboard-body': isPublic }\">\n <div [ngClass]=\"{ 'mt-5': isPublic }\">\n @if (isPublic) {\n <h3>{{ product }}</h3>\n }\n <div>\n\n <ul ngbNav\n #nav=\"ngbNav\"\n [(activeId)]=\"tabId\"\n class=\"nav-tabs\">\n <li [ngbNavItem]=\"'privacy-policy'\">\n <a ngbNavLink>Privacy policy</a>\n <ng-template ngbNavContent>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body pt-1\">\n <div class=\"row\">\n <div class=\"col-12 terms-of-service\">\n <h3>Privacy policy</h3>\n <div class=\"clearfix\"></div>\n <div class=\"ql-container ql-snow body-quill\">\n <div class=\"ql-editor\"\n [innerHTML]=\"data?.privacy\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </li>\n <li [ngbNavItem]=\"'terms-of-service'\">\n <a ngbNavLink>Terms of Services</a>\n <ng-template ngbNavContent>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body pt-1\">\n <div class=\"row\">\n <div class=\"col-12 terms-of-service\">\n <h3>Terms of Services</h3>\n <div class=\"clearfix\"></div>\n <div class=\"ql-container ql-snow body-quill\">\n <div class=\"ql-editor\"\n [innerHTML]=\"data?.tos\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </li>\n </ul>\n </div>\n @if (!isLoaded) {\n <div class=\"w-100 text-center p-2 mt-5\">\n <p-progressSpinner strokeWidth=\"2\"></p-progressSpinner>\n </div>\n }\n @if (isLoaded) {\n <div [ngbNavOutlet]=\"nav\"></div>\n }\n </div>\n </div>\n </div>\n </div>\n", styles: ["::ng-deep .terms-of-service ul{list-style:disc!important;padding-left:40px!important}.ql-container{max-width:1000px;margin:0 auto;resize:none!important}\n"], dependencies: [{ kind: "directive", type: i3$
|
|
2040
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.6", type: PrivacyAndTosComponent, isStandalone: false, selector: "pw-privacy-and-tos", inputs: { productId: "productId" }, usesInheritance: true, ngImport: i0, template: "@if (isPublic) {\n <pw-header [landing]=\"false\"></pw-header>\n}\n\n@if (!isPublic) {\n <div class=\"col-12 d-flex\"\n >\n <a aria-label=\"Navigate to Target\"\n (click)=\"back()\"\n class=\"previous\"><i class=\"fa fa-arrow-alt-circle-left\" aria-hidden=\"true\"></i></a>\n <h3 class=\"mt-3\">{{ productName }}</h3>\n </div>\n }\n\n\n\n\n <div [ngClass]=\"{ 'container pw-tab overflow-hidden': isPublic }\" >\n <div [ngClass]=\"{ dashboard: isPublic }\">\n <div [ngClass]=\"{ 'dashboard-body': isPublic }\">\n <div [ngClass]=\"{ 'mt-5': isPublic }\">\n @if (isPublic) {\n <h3>{{ product }}</h3>\n }\n <div>\n\n <ul ngbNav\n #nav=\"ngbNav\"\n [(activeId)]=\"tabId\"\n class=\"nav-tabs\">\n <li [ngbNavItem]=\"'privacy-policy'\">\n <a ngbNavLink>Privacy policy</a>\n <ng-template ngbNavContent>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body pt-1\">\n <div class=\"row\">\n <div class=\"col-12 terms-of-service\">\n <h3>Privacy policy</h3>\n <div class=\"clearfix\"></div>\n <div class=\"ql-container ql-snow body-quill\">\n <div class=\"ql-editor\"\n [innerHTML]=\"data?.privacy\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </li>\n <li [ngbNavItem]=\"'terms-of-service'\">\n <a ngbNavLink>Terms of Services</a>\n <ng-template ngbNavContent>\n <div class=\"container-fluid pw-tab overflow-hidden\">\n <div class=\"dashboard\">\n <div class=\"dashboard-body pt-1\">\n <div class=\"row\">\n <div class=\"col-12 terms-of-service\">\n <h3>Terms of Services</h3>\n <div class=\"clearfix\"></div>\n <div class=\"ql-container ql-snow body-quill\">\n <div class=\"ql-editor\"\n [innerHTML]=\"data?.tos\">\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </ng-template>\n </li>\n </ul>\n </div>\n @if (!isLoaded) {\n <div class=\"w-100 text-center p-2 mt-5\">\n <p-progressSpinner strokeWidth=\"2\"></p-progressSpinner>\n </div>\n }\n @if (isLoaded) {\n <div [ngbNavOutlet]=\"nav\"></div>\n }\n </div>\n </div>\n </div>\n </div>\n", styles: ["::ng-deep .terms-of-service ul{list-style:disc!important;padding-left:40px!important}.ql-container{max-width:1000px;margin:0 auto;resize:none!important}\n"], dependencies: [{ kind: "directive", type: i3$2.NgbNavContent, selector: "ng-template[ngbNavContent]" }, { kind: "directive", type: i3$2.NgbNav, selector: "[ngbNav]", inputs: ["activeId", "animation", "destroyOnHide", "orientation", "roles", "keyboard"], outputs: ["activeIdChange", "shown", "hidden", "navChange"], exportAs: ["ngbNav"] }, { kind: "directive", type: i3$2.NgbNavItem, selector: "[ngbNavItem]", inputs: ["destroyOnHide", "disabled", "domId", "ngbNavItem"], outputs: ["shown", "hidden"], exportAs: ["ngbNavItem"] }, { kind: "directive", type: i3$2.NgbNavItemRole, selector: "[ngbNavItem]:not(ng-container)" }, { kind: "directive", type: i3$2.NgbNavLink, selector: "a[ngbNavLink]" }, { kind: "directive", type: i3$2.NgbNavLinkBase, selector: "[ngbNavLink]" }, { kind: "component", type: i3$2.NgbNavOutlet, selector: "[ngbNavOutlet]", inputs: ["paneRole", "ngbNavOutlet"] }, { kind: "component", type: i4$1.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: HeaderComponent, selector: "pw-header", inputs: ["landing"] }] }); }
|
|
1836
2041
|
}
|
|
1837
2042
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: PrivacyAndTosComponent, decorators: [{
|
|
1838
2043
|
type: Component,
|
|
@@ -2024,7 +2229,7 @@ class InputContainerComponent {
|
|
|
2024
2229
|
useExisting: InputContainerComponent,
|
|
2025
2230
|
multi: true
|
|
2026
2231
|
}
|
|
2027
|
-
], ngImport: i0, template: "@if (useAriaLabelledbyOnly) {\n <span class=\"pw-input-container-label mb-2 d-block\" [attr.id]=\"controlId ? (controlId + '-label') : null\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span
|
|
2232
|
+
], ngImport: i0, template: "@if (useAriaLabelledbyOnly) {\n <span class=\"pw-input-container-label mb-2 d-block\" [attr.id]=\"controlId ? (controlId + '-label') : null\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span class=\"info-circle tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </span>\n}\n@if (!useAriaLabelledbyOnly) {\n <label class=\"pw-input-container-label mb-2\" [attr.for]=\"controlId || name\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span class=\"info-circle tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </label>\n}\n\n<div class=\"mb-3\">\n <ng-content></ng-content>\n @if (control?.errors) {\n <pw-field-error-display [displayError]=\"control?.invalid && control?.touched\"\n [errorMsg]=\"errorMsg | transloco\">\n </pw-field-error-display>\n }\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.pw-input-container-label{display:block;color:gray;font-size:.75rem;font-weight:500;letter-spacing:2px;text-transform:uppercase}.mandatory:after{color:#ff586b;content:\"*\";padding-left:2px;font-size:15px}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3$3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: i4$2.FieldErrorDisplayComponent, selector: "pw-field-error-display", inputs: ["errorMsg", "displayError"] }, { kind: "pipe", type: i4.TranslocoPipe, name: "transloco" }] }); }
|
|
2028
2233
|
}
|
|
2029
2234
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: InputContainerComponent, decorators: [{
|
|
2030
2235
|
type: Component,
|
|
@@ -2035,7 +2240,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
|
|
|
2035
2240
|
useExisting: InputContainerComponent,
|
|
2036
2241
|
multi: true
|
|
2037
2242
|
}
|
|
2038
|
-
], standalone: false, template: "@if (useAriaLabelledbyOnly) {\n <span class=\"pw-input-container-label mb-2 d-block\" [attr.id]=\"controlId ? (controlId + '-label') : null\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span
|
|
2243
|
+
], standalone: false, template: "@if (useAriaLabelledbyOnly) {\n <span class=\"pw-input-container-label mb-2 d-block\" [attr.id]=\"controlId ? (controlId + '-label') : null\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span class=\"info-circle tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </span>\n}\n@if (!useAriaLabelledbyOnly) {\n <label class=\"pw-input-container-label mb-2\" [attr.for]=\"controlId || name\">\n <span [class]=\"labelClass\"\n [ngClass]=\"{ mandatory: required && !control?.disabled }\">\n {{ label }}\n </span>\n @if (showTooltip && tooltipText) {\n <span class=\"info-circle tooltip-wrap ms-1\"\n [pTooltip]=\"tooltipText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n </span>\n }\n @if (showTriangle) {\n <span class=\"tooltip-wrap ms-1\"\n [pTooltip]=\"'Last month this value was set to ' + showTriangleText\"\n [appendTo]=\"'body'\"\n [tooltipPosition]=\"tooltipPosition || 'top'\">\n <i class=\"fas fa-exclamation-triangle text-warning\"></i>\n </span>\n }\n <!-- after label -->\n @if (afterLabel && showAfterLabel) {\n <span\n [innerHTML]=\"afterLabel\"></span>\n }\n <!-- after label end -->\n </label>\n}\n\n<div class=\"mb-3\">\n <ng-content></ng-content>\n @if (control?.errors) {\n <pw-field-error-display [displayError]=\"control?.invalid && control?.touched\"\n [errorMsg]=\"errorMsg | transloco\">\n </pw-field-error-display>\n }\n</div>\n", styles: [":root{--first: rgb(23 105 225);--second: rgb(54 194 131);--third: rgb(255 171 0);--text: rgb(34 34 34);--tabs_bg: rgb(23 105 225);--tabs_sub_bg: rgb(70, 136, 236);--tabs_text: rgb(255 255 255);--titles: rgb(34 34 34);--sidebar_bg: rgb(0, 48, 63);--sidebar_text: rgb(255 255 255)}.pw-input-container-label{display:block;color:gray;font-size:.75rem;font-weight:500;letter-spacing:2px;text-transform:uppercase}.mandatory:after{color:#ff586b;content:\"*\";padding-left:2px;font-size:15px}\n"] }]
|
|
2039
2244
|
}], ctorParameters: () => [{ type: i2$1.ControlContainer, decorators: [{
|
|
2040
2245
|
type: Optional
|
|
2041
2246
|
}, {
|
|
@@ -2409,7 +2614,7 @@ class CollapsibleSidebarSuperAdminGuard {
|
|
|
2409
2614
|
* Emits true when the signed-in user has {@link PermissionService.isSuperAdmin}.
|
|
2410
2615
|
* UX-only; backend must still enforce permissions.
|
|
2411
2616
|
*/
|
|
2412
|
-
this.canAccessSidebar$ = this.userService.getUserState().pipe(map
|
|
2617
|
+
this.canAccessSidebar$ = this.userService.getUserState().pipe(map(state => CollapsibleSidebarSuperAdminGuard.userIsSuperAdmin(state?.currentUser)), distinctUntilChanged());
|
|
2413
2618
|
}
|
|
2414
2619
|
/**
|
|
2415
2620
|
* Same rule as {@link PermissionService#isSuperAdmin}, safe when user is not loaded.
|