@weaver-apps/service-desk 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -16
- package/fesm2022/weaver-apps-service-desk.mjs +409 -160
- package/fesm2022/weaver-apps-service-desk.mjs.map +1 -1
- package/i18n/{service-desk → weaver-apps-service-desk}/de.json +3 -20
- package/i18n/{service-desk → weaver-apps-service-desk}/en.json +3 -20
- package/package.json +10 -6
- package/types/weaver-apps-service-desk.d.ts +16 -8
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component,
|
|
3
|
-
import { TranslocoPipe, TranslocoService } from "@jsverse/transloco";
|
|
2
|
+
import { CUSTOM_ELEMENTS_SCHEMA, ChangeDetectionStrategy, Component, InjectionToken, computed, inject, input, output, resource, signal, viewChild } from "@angular/core";
|
|
3
|
+
import { TranslocoPipe, TranslocoService, translateObjectSignal } from "@jsverse/transloco";
|
|
4
4
|
import { toSignal } from "@angular/core/rxjs-interop";
|
|
5
5
|
import { ActivatedRoute } from "@angular/router";
|
|
6
6
|
import { map } from "rxjs";
|
|
7
7
|
import { DialogRef } from "@loomweaver/plugin-sdk";
|
|
8
|
+
import { DataGrid, ListFilter, listingDatasource } from "@weaver-apps/data-grid";
|
|
8
9
|
var ServiceDeskGatewayError = class extends Error {
|
|
9
10
|
status;
|
|
10
11
|
constructor(status) {
|
|
@@ -36,7 +37,20 @@ var ServiceDeskHost = class {
|
|
|
36
37
|
}
|
|
37
38
|
};
|
|
38
39
|
const serviceDeskHost = new ServiceDeskHost();
|
|
39
|
-
const
|
|
40
|
+
const serviceDeskPluginId = "weaver-apps-service-desk";
|
|
41
|
+
const serviceDeskContributionIds = {
|
|
42
|
+
desks: `${serviceDeskPluginId}.desks`,
|
|
43
|
+
desk: `${serviceDeskPluginId}.desk`,
|
|
44
|
+
rail: `${serviceDeskPluginId}.rail`
|
|
45
|
+
};
|
|
46
|
+
const serviceDeskIconNames = {
|
|
47
|
+
desk: `${serviceDeskPluginId}.desk`,
|
|
48
|
+
complete: `${serviceDeskPluginId}.complete`,
|
|
49
|
+
cancel: `${serviceDeskPluginId}.cancel`,
|
|
50
|
+
previous: `${serviceDeskPluginId}.previous`,
|
|
51
|
+
next: `${serviceDeskPluginId}.next`
|
|
52
|
+
};
|
|
53
|
+
const deskListPath = serviceDeskPluginId;
|
|
40
54
|
function deskPath(deskId) {
|
|
41
55
|
return `${deskListPath}/${deskId}`;
|
|
42
56
|
}
|
|
@@ -51,9 +65,9 @@ var DeskListPage = class DeskListPage {
|
|
|
51
65
|
}
|
|
52
66
|
async create() {
|
|
53
67
|
const name = await serviceDeskHost.ui.prompt({
|
|
54
|
-
title: "service-desk.desks.create",
|
|
55
|
-
message: "service-desk.desks.createMessage",
|
|
56
|
-
confirmLabel: "service-desk.desks.createConfirm"
|
|
68
|
+
title: "weaver-apps-service-desk.desks.create",
|
|
69
|
+
message: "weaver-apps-service-desk.desks.createMessage",
|
|
70
|
+
confirmLabel: "weaver-apps-service-desk.desks.createConfirm"
|
|
57
71
|
});
|
|
58
72
|
if (!name?.trim()) return;
|
|
59
73
|
try {
|
|
@@ -61,7 +75,7 @@ var DeskListPage = class DeskListPage {
|
|
|
61
75
|
this.open(desk.id);
|
|
62
76
|
} catch {
|
|
63
77
|
serviceDeskHost.ui.toast({
|
|
64
|
-
message: "service-desk.errors.create",
|
|
78
|
+
message: "weaver-apps-service-desk.errors.create",
|
|
65
79
|
kind: "error"
|
|
66
80
|
});
|
|
67
81
|
}
|
|
@@ -81,7 +95,7 @@ var DeskListPage = class DeskListPage {
|
|
|
81
95
|
isStandalone: true,
|
|
82
96
|
selector: "wa-desk-list-page",
|
|
83
97
|
ngImport: i0,
|
|
84
|
-
template: "<div class=\"flex h-full flex-col gap-4 overflow-auto p-6\">\n <div class=\"flex items-center justify-between gap-4\">\n <h2 class=\"text-lg font-semibold text-content\">{{ 'service-desk.desks.title' | transloco }}</h2>\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"create()\">{{ 'service-desk.desks.create' | transloco }}</button>\n </div>\n @if (desks.error()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'service-desk.errors.load' | transloco }}</p>\n } @else if (desks.hasValue()) {\n <ul role=\"list\" class=\"divide-y divide-border rounded-xl border border-border bg-surface\">\n @for (desk of desks.value(); track desk.id) {\n <li>\n <button type=\"button\" class=\"flex w-full items-center gap-3 px-4 py-3 text-left text-sm text-content hover:bg-surface-overlay\" (click)=\"open(desk.id)\">\n <lw-icon name=\"
|
|
98
|
+
template: "<div class=\"flex h-full flex-col gap-4 overflow-auto p-6\">\n <div class=\"flex items-center justify-between gap-4\">\n <h2 class=\"text-lg font-semibold text-content\">{{ 'weaver-apps-service-desk.desks.title' | transloco }}</h2>\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"create()\">{{ 'weaver-apps-service-desk.desks.create' | transloco }}</button>\n </div>\n @if (desks.error()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'weaver-apps-service-desk.errors.load' | transloco }}</p>\n } @else if (desks.hasValue()) {\n <ul role=\"list\" class=\"divide-y divide-border rounded-xl border border-border bg-surface\">\n @for (desk of desks.value(); track desk.id) {\n <li>\n <button type=\"button\" class=\"flex w-full items-center gap-3 px-4 py-3 text-left text-sm text-content hover:bg-surface-overlay\" (click)=\"open(desk.id)\">\n <lw-icon name=\"weaver-apps-service-desk.desk\" size=\"1.25rem\"></lw-icon>\n <span>{{ desk.name }}</span>\n </button>\n </li>\n } @empty {\n <li class=\"px-4 py-8 text-center text-sm text-content-faint\">{{ 'weaver-apps-service-desk.desks.empty' | transloco }}</li>\n }\n </ul>\n }\n</div>\n",
|
|
85
99
|
dependencies: [{
|
|
86
100
|
kind: "pipe",
|
|
87
101
|
type: TranslocoPipe,
|
|
@@ -102,7 +116,7 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
102
116
|
imports: [TranslocoPipe],
|
|
103
117
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
104
118
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
105
|
-
template: "<div class=\"flex h-full flex-col gap-4 overflow-auto p-6\">\n <div class=\"flex items-center justify-between gap-4\">\n <h2 class=\"text-lg font-semibold text-content\">{{ 'service-desk.desks.title' | transloco }}</h2>\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"create()\">{{ 'service-desk.desks.create' | transloco }}</button>\n </div>\n @if (desks.error()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'service-desk.errors.load' | transloco }}</p>\n } @else if (desks.hasValue()) {\n <ul role=\"list\" class=\"divide-y divide-border rounded-xl border border-border bg-surface\">\n @for (desk of desks.value(); track desk.id) {\n <li>\n <button type=\"button\" class=\"flex w-full items-center gap-3 px-4 py-3 text-left text-sm text-content hover:bg-surface-overlay\" (click)=\"open(desk.id)\">\n <lw-icon name=\"
|
|
119
|
+
template: "<div class=\"flex h-full flex-col gap-4 overflow-auto p-6\">\n <div class=\"flex items-center justify-between gap-4\">\n <h2 class=\"text-lg font-semibold text-content\">{{ 'weaver-apps-service-desk.desks.title' | transloco }}</h2>\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"create()\">{{ 'weaver-apps-service-desk.desks.create' | transloco }}</button>\n </div>\n @if (desks.error()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'weaver-apps-service-desk.errors.load' | transloco }}</p>\n } @else if (desks.hasValue()) {\n <ul role=\"list\" class=\"divide-y divide-border rounded-xl border border-border bg-surface\">\n @for (desk of desks.value(); track desk.id) {\n <li>\n <button type=\"button\" class=\"flex w-full items-center gap-3 px-4 py-3 text-left text-sm text-content hover:bg-surface-overlay\" (click)=\"open(desk.id)\">\n <lw-icon name=\"weaver-apps-service-desk.desk\" size=\"1.25rem\"></lw-icon>\n <span>{{ desk.name }}</span>\n </button>\n </li>\n } @empty {\n <li class=\"px-4 py-8 text-center text-sm text-content-faint\">{{ 'weaver-apps-service-desk.desks.empty' | transloco }}</li>\n }\n </ul>\n }\n</div>\n"
|
|
106
120
|
}]
|
|
107
121
|
}]
|
|
108
122
|
});
|
|
@@ -142,14 +156,6 @@ const requestTypes = Object.values(ServiceRequestType);
|
|
|
142
156
|
const requestPriorities = Object.values(ServiceRequestPriority);
|
|
143
157
|
const requestOrigins = Object.values(ServiceRequestOrigin);
|
|
144
158
|
const settableStatuses = [ServiceRequestStatus.open, ServiceRequestStatus.inProgress];
|
|
145
|
-
const statusFilters = [
|
|
146
|
-
"active",
|
|
147
|
-
"open",
|
|
148
|
-
"inProgress",
|
|
149
|
-
"completed",
|
|
150
|
-
"cancelled",
|
|
151
|
-
"all"
|
|
152
|
-
];
|
|
153
159
|
function isClosed(status) {
|
|
154
160
|
return status === ServiceRequestStatus.completed || status === ServiceRequestStatus.cancelled;
|
|
155
161
|
}
|
|
@@ -206,7 +212,7 @@ var RequestDialog = class RequestDialog {
|
|
|
206
212
|
}
|
|
207
213
|
async save() {
|
|
208
214
|
if (!this.title().trim()) {
|
|
209
|
-
this.problem.set("service-desk.dialog.titleRequired");
|
|
215
|
+
this.problem.set("weaver-apps-service-desk.dialog.titleRequired");
|
|
210
216
|
return;
|
|
211
217
|
}
|
|
212
218
|
this.saving.set(true);
|
|
@@ -218,7 +224,7 @@ var RequestDialog = class RequestDialog {
|
|
|
218
224
|
});
|
|
219
225
|
this.settle(await this.applyStatus(outcome));
|
|
220
226
|
} catch {
|
|
221
|
-
this.problem.set("service-desk.errors.save");
|
|
227
|
+
this.problem.set("weaver-apps-service-desk.errors.save");
|
|
222
228
|
} finally {
|
|
223
229
|
this.saving.set(false);
|
|
224
230
|
}
|
|
@@ -257,10 +263,10 @@ var RequestDialog = class RequestDialog {
|
|
|
257
263
|
}
|
|
258
264
|
settle(outcome) {
|
|
259
265
|
const messages = {
|
|
260
|
-
closed: "service-desk.dialog.closed",
|
|
261
|
-
changed: "service-desk.dialog.changed",
|
|
262
|
-
invalid: "service-desk.dialog.invalid",
|
|
263
|
-
missing: "service-desk.dialog.missing"
|
|
266
|
+
closed: "weaver-apps-service-desk.dialog.closed",
|
|
267
|
+
changed: "weaver-apps-service-desk.dialog.changed",
|
|
268
|
+
invalid: "weaver-apps-service-desk.dialog.invalid",
|
|
269
|
+
missing: "weaver-apps-service-desk.dialog.missing"
|
|
264
270
|
};
|
|
265
271
|
if (outcome.kind === "saved") {
|
|
266
272
|
this.dialog.close(true);
|
|
@@ -290,7 +296,7 @@ var RequestDialog = class RequestDialog {
|
|
|
290
296
|
isStandalone: true,
|
|
291
297
|
selector: "wa-request-dialog",
|
|
292
298
|
ngImport: i0,
|
|
293
|
-
template: "<form class=\"flex flex-col gap-4\" (submit)=\"$event.preventDefault(); save()\">\n @if (closed) {\n <p class=\"text-sm text-content-faint\" role=\"status\">\n {{ 'service-desk.dialog.closedNote' | transloco }}\n @if (cancellationReason) {\n {{ 'service-desk.dialog.reason' | transloco: { reason: cancellationReason } }}\n }\n </p>\n }\n\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.title' | transloco }}\n <input class=\"lw-field\" required [disabled]=\"closed\" [value]=\"title()\" (input)=\"bind(title, $event)\" />\n </label>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.type' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"chooseType($event)\">\n @for (choice of types; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === type()\">{{ 'service-desk.type.' + choice | transloco }}</option>\n }\n </select>\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.priority' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"choosePriority($event)\">\n @for (choice of priorities; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === priority()\">{{ 'service-desk.priority.' + choice | transloco }}</option>\n }\n </select>\n </label>\n @if (editing) {\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.status' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"chooseStatus($event)\">\n @if (closed) {\n <option selected>{{ 'service-desk.status.' + status() | transloco }}</option>\n } @else {\n @for (choice of statuses; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === status()\">{{ 'service-desk.status.' + choice | transloco }}</option>\n }\n }\n </select>\n </label>\n } @else {\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.origin' | transloco }}\n <select class=\"lw-field\" (change)=\"chooseOrigin($event)\">\n @for (choice of origins; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === origin()\">{{ 'service-desk.origin.' + choice | transloco }}</option>\n }\n </select>\n </label>\n }\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.contactName' | transloco }}\n <input class=\"lw-field\" [disabled]=\"closed\" [value]=\"contactName()\" (input)=\"bind(contactName, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.contactPhone' | transloco }}\n <input class=\"lw-field\" type=\"tel\" [disabled]=\"closed\" [value]=\"contactPhone()\" (input)=\"bind(contactPhone, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.contactEmail' | transloco }}\n <input class=\"lw-field\" type=\"email\" [disabled]=\"closed\" [value]=\"contactEmail()\" (input)=\"bind(contactEmail, $event)\" />\n </label>\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.assignee' | transloco }}\n <input class=\"lw-field\" [disabled]=\"closed\" [value]=\"assignee()\" (input)=\"bind(assignee, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.due' | transloco }}\n <input class=\"lw-field\" type=\"date\" [disabled]=\"closed\" [value]=\"dueDate()\" (input)=\"bind(dueDate, $event)\" />\n </label>\n </div>\n\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.description' | transloco }}\n <textarea class=\"lw-field\" rows=\"3\" [disabled]=\"closed\" [value]=\"description()\" (input)=\"bind(description, $event)\"></textarea>\n </label>\n\n @if (problem()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ problem() | transloco }}</p>\n }\n\n <div class=\"flex justify-end gap-2\">\n <button type=\"button\" class=\"lw-btn lw-btn--default\" (click)=\"close()\">{{ (closed ? 'service-desk.dialog.close' : 'service-desk.dialog.cancel') | transloco }}</button>\n @if (!closed) {\n <button type=\"submit\" class=\"lw-btn lw-btn--primary\" [disabled]=\"saving()\">{{ 'service-desk.dialog.save' | transloco }}</button>\n }\n </div>\n</form>\n",
|
|
299
|
+
template: "<form class=\"flex flex-col gap-4\" (submit)=\"$event.preventDefault(); save()\">\n @if (closed) {\n <p class=\"text-sm text-content-faint\" role=\"status\">\n {{ 'weaver-apps-service-desk.dialog.closedNote' | transloco }}\n @if (cancellationReason) {\n {{ 'weaver-apps-service-desk.dialog.reason' | transloco: { reason: cancellationReason } }}\n }\n </p>\n }\n\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.title' | transloco }}\n <input class=\"lw-field\" required [disabled]=\"closed\" [value]=\"title()\" (input)=\"bind(title, $event)\" />\n </label>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.type' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"chooseType($event)\">\n @for (choice of types; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === type()\">{{ 'weaver-apps-service-desk.type.' + choice | transloco }}</option>\n }\n </select>\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.priority' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"choosePriority($event)\">\n @for (choice of priorities; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === priority()\">{{ 'weaver-apps-service-desk.priority.' + choice | transloco }}</option>\n }\n </select>\n </label>\n @if (editing) {\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.status' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"chooseStatus($event)\">\n @if (closed) {\n <option selected>{{ 'weaver-apps-service-desk.status.' + status() | transloco }}</option>\n } @else {\n @for (choice of statuses; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === status()\">{{ 'weaver-apps-service-desk.status.' + choice | transloco }}</option>\n }\n }\n </select>\n </label>\n } @else {\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.origin' | transloco }}\n <select class=\"lw-field\" (change)=\"chooseOrigin($event)\">\n @for (choice of origins; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === origin()\">{{ 'weaver-apps-service-desk.origin.' + choice | transloco }}</option>\n }\n </select>\n </label>\n }\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.contactName' | transloco }}\n <input class=\"lw-field\" [disabled]=\"closed\" [value]=\"contactName()\" (input)=\"bind(contactName, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.contactPhone' | transloco }}\n <input class=\"lw-field\" type=\"tel\" [disabled]=\"closed\" [value]=\"contactPhone()\" (input)=\"bind(contactPhone, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.contactEmail' | transloco }}\n <input class=\"lw-field\" type=\"email\" [disabled]=\"closed\" [value]=\"contactEmail()\" (input)=\"bind(contactEmail, $event)\" />\n </label>\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.assignee' | transloco }}\n <input class=\"lw-field\" [disabled]=\"closed\" [value]=\"assignee()\" (input)=\"bind(assignee, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.due' | transloco }}\n <input class=\"lw-field\" type=\"date\" [disabled]=\"closed\" [value]=\"dueDate()\" (input)=\"bind(dueDate, $event)\" />\n </label>\n </div>\n\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.description' | transloco }}\n <textarea class=\"lw-field\" rows=\"3\" [disabled]=\"closed\" [value]=\"description()\" (input)=\"bind(description, $event)\"></textarea>\n </label>\n\n @if (problem()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ problem() | transloco }}</p>\n }\n\n <div class=\"flex justify-end gap-2\">\n <button type=\"button\" class=\"lw-btn lw-btn--default\" (click)=\"close()\">{{ (closed ? 'weaver-apps-service-desk.dialog.close' : 'weaver-apps-service-desk.dialog.cancel') | transloco }}</button>\n @if (!closed) {\n <button type=\"submit\" class=\"lw-btn lw-btn--primary\" [disabled]=\"saving()\">{{ 'weaver-apps-service-desk.dialog.save' | transloco }}</button>\n }\n </div>\n</form>\n",
|
|
294
300
|
dependencies: [{
|
|
295
301
|
kind: "pipe",
|
|
296
302
|
type: TranslocoPipe,
|
|
@@ -310,45 +316,287 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
310
316
|
selector: "wa-request-dialog",
|
|
311
317
|
imports: [TranslocoPipe],
|
|
312
318
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
313
|
-
template: "<form class=\"flex flex-col gap-4\" (submit)=\"$event.preventDefault(); save()\">\n @if (closed) {\n <p class=\"text-sm text-content-faint\" role=\"status\">\n {{ 'service-desk.dialog.closedNote' | transloco }}\n @if (cancellationReason) {\n {{ 'service-desk.dialog.reason' | transloco: { reason: cancellationReason } }}\n }\n </p>\n }\n\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.title' | transloco }}\n <input class=\"lw-field\" required [disabled]=\"closed\" [value]=\"title()\" (input)=\"bind(title, $event)\" />\n </label>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.type' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"chooseType($event)\">\n @for (choice of types; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === type()\">{{ 'service-desk.type.' + choice | transloco }}</option>\n }\n </select>\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.priority' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"choosePriority($event)\">\n @for (choice of priorities; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === priority()\">{{ 'service-desk.priority.' + choice | transloco }}</option>\n }\n </select>\n </label>\n @if (editing) {\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.status' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"chooseStatus($event)\">\n @if (closed) {\n <option selected>{{ 'service-desk.status.' + status() | transloco }}</option>\n } @else {\n @for (choice of statuses; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === status()\">{{ 'service-desk.status.' + choice | transloco }}</option>\n }\n }\n </select>\n </label>\n } @else {\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.origin' | transloco }}\n <select class=\"lw-field\" (change)=\"chooseOrigin($event)\">\n @for (choice of origins; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === origin()\">{{ 'service-desk.origin.' + choice | transloco }}</option>\n }\n </select>\n </label>\n }\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.contactName' | transloco }}\n <input class=\"lw-field\" [disabled]=\"closed\" [value]=\"contactName()\" (input)=\"bind(contactName, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.contactPhone' | transloco }}\n <input class=\"lw-field\" type=\"tel\" [disabled]=\"closed\" [value]=\"contactPhone()\" (input)=\"bind(contactPhone, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.contactEmail' | transloco }}\n <input class=\"lw-field\" type=\"email\" [disabled]=\"closed\" [value]=\"contactEmail()\" (input)=\"bind(contactEmail, $event)\" />\n </label>\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.assignee' | transloco }}\n <input class=\"lw-field\" [disabled]=\"closed\" [value]=\"assignee()\" (input)=\"bind(assignee, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.due' | transloco }}\n <input class=\"lw-field\" type=\"date\" [disabled]=\"closed\" [value]=\"dueDate()\" (input)=\"bind(dueDate, $event)\" />\n </label>\n </div>\n\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'service-desk.fields.description' | transloco }}\n <textarea class=\"lw-field\" rows=\"3\" [disabled]=\"closed\" [value]=\"description()\" (input)=\"bind(description, $event)\"></textarea>\n </label>\n\n @if (problem()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ problem() | transloco }}</p>\n }\n\n <div class=\"flex justify-end gap-2\">\n <button type=\"button\" class=\"lw-btn lw-btn--default\" (click)=\"close()\">{{ (closed ? 'service-desk.dialog.close' : 'service-desk.dialog.cancel') | transloco }}</button>\n @if (!closed) {\n <button type=\"submit\" class=\"lw-btn lw-btn--primary\" [disabled]=\"saving()\">{{ 'service-desk.dialog.save' | transloco }}</button>\n }\n </div>\n</form>\n"
|
|
319
|
+
template: "<form class=\"flex flex-col gap-4\" (submit)=\"$event.preventDefault(); save()\">\n @if (closed) {\n <p class=\"text-sm text-content-faint\" role=\"status\">\n {{ 'weaver-apps-service-desk.dialog.closedNote' | transloco }}\n @if (cancellationReason) {\n {{ 'weaver-apps-service-desk.dialog.reason' | transloco: { reason: cancellationReason } }}\n }\n </p>\n }\n\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.title' | transloco }}\n <input class=\"lw-field\" required [disabled]=\"closed\" [value]=\"title()\" (input)=\"bind(title, $event)\" />\n </label>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.type' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"chooseType($event)\">\n @for (choice of types; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === type()\">{{ 'weaver-apps-service-desk.type.' + choice | transloco }}</option>\n }\n </select>\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.priority' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"choosePriority($event)\">\n @for (choice of priorities; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === priority()\">{{ 'weaver-apps-service-desk.priority.' + choice | transloco }}</option>\n }\n </select>\n </label>\n @if (editing) {\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.status' | transloco }}\n <select class=\"lw-field\" [disabled]=\"closed\" (change)=\"chooseStatus($event)\">\n @if (closed) {\n <option selected>{{ 'weaver-apps-service-desk.status.' + status() | transloco }}</option>\n } @else {\n @for (choice of statuses; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === status()\">{{ 'weaver-apps-service-desk.status.' + choice | transloco }}</option>\n }\n }\n </select>\n </label>\n } @else {\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.origin' | transloco }}\n <select class=\"lw-field\" (change)=\"chooseOrigin($event)\">\n @for (choice of origins; track choice) {\n <option [value]=\"choice\" [selected]=\"choice === origin()\">{{ 'weaver-apps-service-desk.origin.' + choice | transloco }}</option>\n }\n </select>\n </label>\n }\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-3\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.contactName' | transloco }}\n <input class=\"lw-field\" [disabled]=\"closed\" [value]=\"contactName()\" (input)=\"bind(contactName, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.contactPhone' | transloco }}\n <input class=\"lw-field\" type=\"tel\" [disabled]=\"closed\" [value]=\"contactPhone()\" (input)=\"bind(contactPhone, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.contactEmail' | transloco }}\n <input class=\"lw-field\" type=\"email\" [disabled]=\"closed\" [value]=\"contactEmail()\" (input)=\"bind(contactEmail, $event)\" />\n </label>\n </div>\n\n <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2\">\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.assignee' | transloco }}\n <input class=\"lw-field\" [disabled]=\"closed\" [value]=\"assignee()\" (input)=\"bind(assignee, $event)\" />\n </label>\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.due' | transloco }}\n <input class=\"lw-field\" type=\"date\" [disabled]=\"closed\" [value]=\"dueDate()\" (input)=\"bind(dueDate, $event)\" />\n </label>\n </div>\n\n <label class=\"flex flex-col gap-1 text-sm text-content\">\n {{ 'weaver-apps-service-desk.fields.description' | transloco }}\n <textarea class=\"lw-field\" rows=\"3\" [disabled]=\"closed\" [value]=\"description()\" (input)=\"bind(description, $event)\"></textarea>\n </label>\n\n @if (problem()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ problem() | transloco }}</p>\n }\n\n <div class=\"flex justify-end gap-2\">\n <button type=\"button\" class=\"lw-btn lw-btn--default\" (click)=\"close()\">{{ (closed ? 'weaver-apps-service-desk.dialog.close' : 'weaver-apps-service-desk.dialog.cancel') | transloco }}</button>\n @if (!closed) {\n <button type=\"submit\" class=\"lw-btn lw-btn--primary\" [disabled]=\"saving()\">{{ 'weaver-apps-service-desk.dialog.save' | transloco }}</button>\n }\n </div>\n</form>\n"
|
|
314
320
|
}]
|
|
315
321
|
}]
|
|
316
322
|
});
|
|
317
|
-
var
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
323
|
+
var RequestCell = class RequestCell {
|
|
324
|
+
params = null;
|
|
325
|
+
kind = signal("title", ...ngDevMode ? [{ debugName: "kind" }] : /* istanbul ignore next */ []);
|
|
326
|
+
request = signal(null, ...ngDevMode ? [{ debugName: "request" }] : /* istanbul ignore next */ []);
|
|
327
|
+
locale = signal("en", ...ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []);
|
|
328
|
+
closed = computed(() => {
|
|
329
|
+
const request = this.request();
|
|
330
|
+
return request !== null && isClosed(request.status);
|
|
331
|
+
}, ...ngDevMode ? [{ debugName: "closed" }] : /* istanbul ignore next */ []);
|
|
332
|
+
dates = computed(() => {
|
|
333
|
+
const request = this.request();
|
|
322
334
|
const date = new Intl.DateTimeFormat(this.locale(), {
|
|
323
335
|
day: "2-digit",
|
|
324
336
|
month: "2-digit",
|
|
325
337
|
year: "numeric"
|
|
326
338
|
});
|
|
327
|
-
return
|
|
339
|
+
return {
|
|
340
|
+
raised: request ? date.format(new Date(request.raisedAt)) : "",
|
|
341
|
+
due: request?.dueAt ? date.format(new Date(request.dueAt)) : ""
|
|
342
|
+
};
|
|
343
|
+
}, ...ngDevMode ? [{ debugName: "dates" }] : /* istanbul ignore next */ []);
|
|
344
|
+
agInit(params) {
|
|
345
|
+
this.params = params;
|
|
346
|
+
this.kind.set(params.kind);
|
|
347
|
+
this.request.set(params.data ?? null);
|
|
348
|
+
this.locale.set(params.locale());
|
|
349
|
+
}
|
|
350
|
+
refresh(params) {
|
|
351
|
+
this.agInit(params);
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
openActions(event) {
|
|
355
|
+
const request = this.request();
|
|
356
|
+
if (request) this.params?.actions({
|
|
328
357
|
request,
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
}, ...ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []);
|
|
358
|
+
x: event.clientX,
|
|
359
|
+
y: event.clientY
|
|
360
|
+
});
|
|
361
|
+
}
|
|
334
362
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
335
363
|
minVersion: "12.0.0",
|
|
336
364
|
version: "22.2.3",
|
|
337
365
|
ngImport: i0,
|
|
338
|
-
type:
|
|
366
|
+
type: RequestCell,
|
|
339
367
|
deps: [],
|
|
340
368
|
target: i0.ɵɵFactoryTarget.Component
|
|
341
369
|
});
|
|
342
370
|
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
343
371
|
minVersion: "17.0.0",
|
|
344
372
|
version: "22.2.3",
|
|
345
|
-
type:
|
|
373
|
+
type: RequestCell,
|
|
346
374
|
isStandalone: true,
|
|
347
|
-
selector: "wa-request-
|
|
375
|
+
selector: "wa-request-cell",
|
|
376
|
+
ngImport: i0,
|
|
377
|
+
template: "@if (request(); as request) {\n @switch (kind()) {\n @case ('title') {\n <span class=\"font-medium\" [class.text-content]=\"!closed()\" [class.line-through]=\"request.status === 'cancelled'\" data-testid=\"request-title\">{{ request.title }}</span>\n }\n @case ('type') {\n <span class=\"rounded-full border border-border px-2 py-0.5 text-xs text-content\">{{ 'weaver-apps-service-desk.type.' + request.type | transloco }}</span>\n }\n @case ('priority') {\n <span class=\"rounded-full border border-border px-2 py-0.5 text-xs\" [class.text-negative]=\"request.priority === 'urgent'\" [class.font-semibold]=\"request.priority === 'urgent' || request.priority === 'high'\" data-testid=\"request-priority\">{{ 'weaver-apps-service-desk.priority.' + request.priority | transloco }}</span>\n }\n @case ('status') {\n <span class=\"rounded-full border border-border px-2 py-0.5 text-xs text-content\" data-testid=\"request-status\">{{ 'weaver-apps-service-desk.status.' + request.status | transloco }}</span>\n }\n @case ('contact') {\n <span>{{ request.contactName ?? '–' }}</span>\n @if (request.contactPhone ?? request.contactEmail; as reach) {\n <span class=\"ml-2 text-content-faint\">{{ reach }}</span>\n }\n }\n @case ('raised') {\n <span>{{ dates().raised }}</span>\n }\n @case ('due') {\n <span>{{ dates().due }}</span>\n }\n @case ('actions') {\n <button type=\"button\" class=\"relative lw-btn lw-btn--ghost lw-btn--sm lw-btn--icon\" [attr.aria-label]=\"'weaver-apps-service-desk.actions.more' | transloco\" (click)=\"openActions($event)\">\n <lw-icon name=\"more\" size=\"1rem\"></lw-icon>\n </button>\n }\n }\n}\n",
|
|
378
|
+
dependencies: [{
|
|
379
|
+
kind: "pipe",
|
|
380
|
+
type: TranslocoPipe,
|
|
381
|
+
name: "transloco"
|
|
382
|
+
}],
|
|
383
|
+
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
384
|
+
});
|
|
385
|
+
};
|
|
386
|
+
i0.ɵɵngDeclareClassMetadata({
|
|
387
|
+
minVersion: "12.0.0",
|
|
388
|
+
version: "22.2.3",
|
|
389
|
+
ngImport: i0,
|
|
390
|
+
type: RequestCell,
|
|
391
|
+
decorators: [{
|
|
392
|
+
type: Component,
|
|
393
|
+
args: [{
|
|
394
|
+
selector: "wa-request-cell",
|
|
395
|
+
imports: [TranslocoPipe],
|
|
396
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
397
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
398
|
+
template: "@if (request(); as request) {\n @switch (kind()) {\n @case ('title') {\n <span class=\"font-medium\" [class.text-content]=\"!closed()\" [class.line-through]=\"request.status === 'cancelled'\" data-testid=\"request-title\">{{ request.title }}</span>\n }\n @case ('type') {\n <span class=\"rounded-full border border-border px-2 py-0.5 text-xs text-content\">{{ 'weaver-apps-service-desk.type.' + request.type | transloco }}</span>\n }\n @case ('priority') {\n <span class=\"rounded-full border border-border px-2 py-0.5 text-xs\" [class.text-negative]=\"request.priority === 'urgent'\" [class.font-semibold]=\"request.priority === 'urgent' || request.priority === 'high'\" data-testid=\"request-priority\">{{ 'weaver-apps-service-desk.priority.' + request.priority | transloco }}</span>\n }\n @case ('status') {\n <span class=\"rounded-full border border-border px-2 py-0.5 text-xs text-content\" data-testid=\"request-status\">{{ 'weaver-apps-service-desk.status.' + request.status | transloco }}</span>\n }\n @case ('contact') {\n <span>{{ request.contactName ?? '–' }}</span>\n @if (request.contactPhone ?? request.contactEmail; as reach) {\n <span class=\"ml-2 text-content-faint\">{{ reach }}</span>\n }\n }\n @case ('raised') {\n <span>{{ dates().raised }}</span>\n }\n @case ('due') {\n <span>{{ dates().due }}</span>\n }\n @case ('actions') {\n <button type=\"button\" class=\"relative lw-btn lw-btn--ghost lw-btn--sm lw-btn--icon\" [attr.aria-label]=\"'weaver-apps-service-desk.actions.more' | transloco\" (click)=\"openActions($event)\">\n <lw-icon name=\"more\" size=\"1rem\"></lw-icon>\n </button>\n }\n }\n}\n"
|
|
399
|
+
}]
|
|
400
|
+
}]
|
|
401
|
+
});
|
|
402
|
+
const requestColumn = {
|
|
403
|
+
title: "title",
|
|
404
|
+
type: "type",
|
|
405
|
+
priority: "priority",
|
|
406
|
+
status: "status",
|
|
407
|
+
contact: "contact",
|
|
408
|
+
raised: "raisedAt",
|
|
409
|
+
due: "dueAt",
|
|
410
|
+
actions: "actions"
|
|
411
|
+
};
|
|
412
|
+
const defaultStatuses = [
|
|
413
|
+
ServiceRequestStatus.open,
|
|
414
|
+
ServiceRequestStatus.inProgress,
|
|
415
|
+
ServiceRequestStatus.completed
|
|
416
|
+
];
|
|
417
|
+
const defaultRequestFilter = { [requestColumn.status]: { values: [...defaultStatuses] } };
|
|
418
|
+
const sortableColumns = /* @__PURE__ */ new Set([
|
|
419
|
+
requestColumn.title,
|
|
420
|
+
requestColumn.priority,
|
|
421
|
+
requestColumn.status,
|
|
422
|
+
requestColumn.raised,
|
|
423
|
+
requestColumn.due
|
|
424
|
+
]);
|
|
425
|
+
function listingOf(request) {
|
|
426
|
+
const { filters, sort } = request;
|
|
427
|
+
return {
|
|
428
|
+
...sort && sortableColumns.has(sort.column) ? {
|
|
429
|
+
sort: sort.column,
|
|
430
|
+
descending: sort.descending
|
|
431
|
+
} : {},
|
|
432
|
+
...textOf("text", filters[requestColumn.title]),
|
|
433
|
+
...textOf("contact", filters[requestColumn.contact]),
|
|
434
|
+
...valuesOf("type", filters[requestColumn.type]),
|
|
435
|
+
...valuesOf("status", filters[requestColumn.status]),
|
|
436
|
+
...valuesOf("priority", filters[requestColumn.priority]),
|
|
437
|
+
offset: request.offset,
|
|
438
|
+
limit: request.limit
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
function textOf(key, filter) {
|
|
442
|
+
const text = filter?.filter?.trim();
|
|
443
|
+
return text ? { [key]: text } : {};
|
|
444
|
+
}
|
|
445
|
+
function valuesOf(key, filter) {
|
|
446
|
+
const values = filter?.values ?? [];
|
|
447
|
+
return values.length > 0 ? { [key]: [...values] } : {};
|
|
448
|
+
}
|
|
449
|
+
const allStatuses = [
|
|
450
|
+
"open",
|
|
451
|
+
"inProgress",
|
|
452
|
+
"completed",
|
|
453
|
+
"cancelled"
|
|
454
|
+
];
|
|
455
|
+
const actionsWidthPx = 72;
|
|
456
|
+
const titleMinWidthPx = 160;
|
|
457
|
+
const contactMinWidthPx = 140;
|
|
458
|
+
const narrowMinWidthPx = 112;
|
|
459
|
+
var RequestGrid = class RequestGrid {
|
|
460
|
+
table = translateObjectSignal("weaver-apps-service-desk.table");
|
|
461
|
+
types = translateObjectSignal("weaver-apps-service-desk.type");
|
|
462
|
+
statuses = translateObjectSignal("weaver-apps-service-desk.status");
|
|
463
|
+
priorities = translateObjectSignal("weaver-apps-service-desk.priority");
|
|
464
|
+
api = null;
|
|
465
|
+
fetch = input.required(...ngDevMode ? [{ debugName: "fetch" }] : /* istanbul ignore next */ []);
|
|
466
|
+
locale = input.required(...ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []);
|
|
467
|
+
requestActions = output();
|
|
468
|
+
counted = output();
|
|
469
|
+
failed = output();
|
|
470
|
+
translated = computed(() => typeof this.table() === "object" && typeof this.table()["title"] === "string", ...ngDevMode ? [{ debugName: "translated" }] : /* istanbul ignore next */ []);
|
|
471
|
+
empty = computed(() => ({ noRowsToShow: this.table()["empty"] ?? "" }), ...ngDevMode ? [{ debugName: "empty" }] : /* istanbul ignore next */ []);
|
|
472
|
+
options = computed(() => ({
|
|
473
|
+
columnDefs: this.columns(this.table()),
|
|
474
|
+
defaultColDef: {
|
|
475
|
+
sortable: false,
|
|
476
|
+
resizable: true,
|
|
477
|
+
suppressHeaderMenuButton: true
|
|
478
|
+
},
|
|
479
|
+
datasource: listingDatasource(this.fetch(), {
|
|
480
|
+
answered: (answer) => this.counted.emit(answer.total),
|
|
481
|
+
failed: () => this.failed.emit()
|
|
482
|
+
}),
|
|
483
|
+
initialState: {
|
|
484
|
+
sort: { sortModel: [{
|
|
485
|
+
colId: requestColumn.raised,
|
|
486
|
+
sort: "desc"
|
|
487
|
+
}] },
|
|
488
|
+
filter: { filterModel: { ...defaultRequestFilter } }
|
|
489
|
+
},
|
|
490
|
+
rowClassRules: { "text-content-faint": (params) => !!params.data && isClosed(params.data.status) }
|
|
491
|
+
}), ...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
|
|
492
|
+
reload() {
|
|
493
|
+
this.api?.refreshInfiniteCache();
|
|
494
|
+
}
|
|
495
|
+
ready(api) {
|
|
496
|
+
this.api = api;
|
|
497
|
+
}
|
|
498
|
+
columns(table) {
|
|
499
|
+
const narrow = {
|
|
500
|
+
flex: 1,
|
|
501
|
+
minWidth: narrowMinWidthPx
|
|
502
|
+
};
|
|
503
|
+
return [
|
|
504
|
+
{
|
|
505
|
+
...this.cell(requestColumn.title, "title", table["title"]),
|
|
506
|
+
sortable: true,
|
|
507
|
+
flex: 3,
|
|
508
|
+
minWidth: titleMinWidthPx,
|
|
509
|
+
filter: "agTextColumnFilter",
|
|
510
|
+
filterParams: {
|
|
511
|
+
filterOptions: ["contains"],
|
|
512
|
+
maxNumConditions: 1
|
|
513
|
+
}
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
...this.cell(requestColumn.type, "type", table["type"]),
|
|
517
|
+
...narrow,
|
|
518
|
+
filter: ListFilter,
|
|
519
|
+
filterParams: this.choices(requestTypes, this.types)
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
...this.cell(requestColumn.priority, "priority", table["priority"]),
|
|
523
|
+
...narrow,
|
|
524
|
+
sortable: true,
|
|
525
|
+
filter: ListFilter,
|
|
526
|
+
filterParams: this.choices(requestPriorities, this.priorities)
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
...this.cell(requestColumn.status, "status", table["status"]),
|
|
530
|
+
...narrow,
|
|
531
|
+
sortable: true,
|
|
532
|
+
filter: ListFilter,
|
|
533
|
+
filterParams: this.choices(allStatuses, this.statuses)
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
...this.cell(requestColumn.contact, "contact", table["contact"]),
|
|
537
|
+
flex: 2,
|
|
538
|
+
minWidth: contactMinWidthPx,
|
|
539
|
+
filter: "agTextColumnFilter",
|
|
540
|
+
filterParams: {
|
|
541
|
+
filterOptions: ["contains"],
|
|
542
|
+
maxNumConditions: 1
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
{
|
|
546
|
+
...this.cell(requestColumn.raised, "raised", table["raised"]),
|
|
547
|
+
...narrow,
|
|
548
|
+
sortable: true,
|
|
549
|
+
sortingOrder: ["desc", "asc"]
|
|
550
|
+
},
|
|
551
|
+
{
|
|
552
|
+
...this.cell(requestColumn.due, "due", table["due"]),
|
|
553
|
+
...narrow,
|
|
554
|
+
sortable: true
|
|
555
|
+
},
|
|
556
|
+
{
|
|
557
|
+
...this.cell(requestColumn.actions, "actions", ""),
|
|
558
|
+
width: actionsWidthPx,
|
|
559
|
+
resizable: false,
|
|
560
|
+
sortable: false
|
|
561
|
+
}
|
|
562
|
+
];
|
|
563
|
+
}
|
|
564
|
+
cell(colId, kind, headerName) {
|
|
565
|
+
return {
|
|
566
|
+
colId,
|
|
567
|
+
headerName: headerName ?? "",
|
|
568
|
+
cellRenderer: RequestCell,
|
|
569
|
+
cellRendererParams: {
|
|
570
|
+
kind,
|
|
571
|
+
locale: () => this.locale(),
|
|
572
|
+
actions: (actions) => this.requestActions.emit(actions)
|
|
573
|
+
}
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
choices(values, labels) {
|
|
577
|
+
return { options: () => values.map((value) => ({
|
|
578
|
+
value,
|
|
579
|
+
label: labels()[value] ?? value
|
|
580
|
+
})) };
|
|
581
|
+
}
|
|
582
|
+
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
583
|
+
minVersion: "12.0.0",
|
|
584
|
+
version: "22.2.3",
|
|
585
|
+
ngImport: i0,
|
|
586
|
+
type: RequestGrid,
|
|
587
|
+
deps: [],
|
|
588
|
+
target: i0.ɵɵFactoryTarget.Component
|
|
589
|
+
});
|
|
590
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({
|
|
591
|
+
minVersion: "17.0.0",
|
|
592
|
+
version: "22.2.3",
|
|
593
|
+
type: RequestGrid,
|
|
594
|
+
isStandalone: true,
|
|
595
|
+
selector: "wa-request-grid",
|
|
348
596
|
inputs: {
|
|
349
|
-
|
|
350
|
-
classPropertyName: "
|
|
351
|
-
publicName: "
|
|
597
|
+
fetch: {
|
|
598
|
+
classPropertyName: "fetch",
|
|
599
|
+
publicName: "fetch",
|
|
352
600
|
isSignal: true,
|
|
353
601
|
isRequired: true,
|
|
354
602
|
transformFunction: null
|
|
@@ -361,13 +609,20 @@ var RequestTable = class RequestTable {
|
|
|
361
609
|
transformFunction: null
|
|
362
610
|
}
|
|
363
611
|
},
|
|
364
|
-
outputs: {
|
|
612
|
+
outputs: {
|
|
613
|
+
requestActions: "requestActions",
|
|
614
|
+
counted: "counted",
|
|
615
|
+
failed: "failed"
|
|
616
|
+
},
|
|
617
|
+
host: { classAttribute: "block h-full w-full" },
|
|
365
618
|
ngImport: i0,
|
|
366
|
-
template: "
|
|
619
|
+
template: "@if (translated()) {\n <wa-data-grid [options]=\"options()\" [localeOverrides]=\"empty()\" (ready)=\"ready($event)\" />\n}\n",
|
|
367
620
|
dependencies: [{
|
|
368
|
-
kind: "
|
|
369
|
-
type:
|
|
370
|
-
|
|
621
|
+
kind: "component",
|
|
622
|
+
type: DataGrid,
|
|
623
|
+
selector: "wa-data-grid",
|
|
624
|
+
inputs: ["options", "localeOverrides"],
|
|
625
|
+
outputs: ["ready"]
|
|
371
626
|
}],
|
|
372
627
|
changeDetection: i0.ChangeDetectionStrategy.OnPush
|
|
373
628
|
});
|
|
@@ -376,23 +631,23 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
376
631
|
minVersion: "12.0.0",
|
|
377
632
|
version: "22.2.3",
|
|
378
633
|
ngImport: i0,
|
|
379
|
-
type:
|
|
634
|
+
type: RequestGrid,
|
|
380
635
|
decorators: [{
|
|
381
636
|
type: Component,
|
|
382
637
|
args: [{
|
|
383
|
-
selector: "wa-request-
|
|
384
|
-
imports: [
|
|
385
|
-
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
638
|
+
selector: "wa-request-grid",
|
|
639
|
+
imports: [DataGrid],
|
|
386
640
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
387
|
-
|
|
641
|
+
host: { class: "block h-full w-full" },
|
|
642
|
+
template: "@if (translated()) {\n <wa-data-grid [options]=\"options()\" [localeOverrides]=\"empty()\" (ready)=\"ready($event)\" />\n}\n"
|
|
388
643
|
}]
|
|
389
644
|
}],
|
|
390
645
|
propDecorators: {
|
|
391
|
-
|
|
646
|
+
fetch: [{
|
|
392
647
|
type: i0.Input,
|
|
393
648
|
args: [{
|
|
394
649
|
isSignal: true,
|
|
395
|
-
alias: "
|
|
650
|
+
alias: "fetch",
|
|
396
651
|
required: true
|
|
397
652
|
}]
|
|
398
653
|
}],
|
|
@@ -407,105 +662,72 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
407
662
|
requestActions: [{
|
|
408
663
|
type: i0.Output,
|
|
409
664
|
args: ["requestActions"]
|
|
665
|
+
}],
|
|
666
|
+
counted: [{
|
|
667
|
+
type: i0.Output,
|
|
668
|
+
args: ["counted"]
|
|
669
|
+
}],
|
|
670
|
+
failed: [{
|
|
671
|
+
type: i0.Output,
|
|
672
|
+
args: ["failed"]
|
|
410
673
|
}]
|
|
411
674
|
}
|
|
412
675
|
});
|
|
413
|
-
const pageSize = 25;
|
|
414
|
-
const searchDelayMs = 300;
|
|
415
676
|
var DeskPage = class DeskPage {
|
|
416
677
|
gateway = inject(SERVICE_DESK_GATEWAY);
|
|
417
678
|
route = inject(ActivatedRoute);
|
|
418
|
-
|
|
679
|
+
grid = viewChild(RequestGrid, ...ngDevMode ? [{ debugName: "grid" }] : /* istanbul ignore next */ []);
|
|
419
680
|
locale = activeLocale();
|
|
420
|
-
filters = statusFilters;
|
|
421
681
|
deskId = toSignal(this.route.paramMap.pipe(map((params) => params.get("deskId") ?? "")), { initialValue: this.route.snapshot.paramMap.get("deskId") ?? "" });
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
offset = signal(0, ...ngDevMode ? [{ debugName: "offset" }] : /* istanbul ignore next */ []);
|
|
682
|
+
count = signal(null, ...ngDevMode ? [{ debugName: "count" }] : /* istanbul ignore next */ []);
|
|
683
|
+
loadFailed = signal(false, ...ngDevMode ? [{ debugName: "loadFailed" }] : /* istanbul ignore next */ []);
|
|
425
684
|
desk = resource({
|
|
426
685
|
...ngDevMode ? { debugName: "desk" } : /* istanbul ignore next */ {},
|
|
427
686
|
params: () => this.deskId(),
|
|
428
687
|
loader: ({ params }) => this.gateway.desk(params)
|
|
429
688
|
});
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
loader: ({ params, abortSignal }) => this.gateway.requests(params.deskId, {
|
|
439
|
-
text: params.text || void 0,
|
|
440
|
-
...params.filter === "active" ? {} : params.filter === "all" ? { includeCancelled: true } : { status: params.filter },
|
|
441
|
-
offset: params.offset,
|
|
442
|
-
limit: pageSize
|
|
443
|
-
}, abortSignal)
|
|
444
|
-
});
|
|
445
|
-
constructor() {
|
|
446
|
-
inject(DestroyRef).onDestroy(() => clearTimeout(this.searchTimer));
|
|
447
|
-
effect(() => {
|
|
448
|
-
const total = this.total();
|
|
449
|
-
if (this.page.hasValue() && this.offset() > 0 && this.offset() >= total) this.offset.set(Math.max(0, Math.ceil(total / pageSize) - 1) * pageSize);
|
|
450
|
-
});
|
|
451
|
-
}
|
|
452
|
-
total = computed(() => Number(this.page.value()?.total ?? 0), ...ngDevMode ? [{ debugName: "total" }] : /* istanbul ignore next */ []);
|
|
453
|
-
range = computed(() => {
|
|
454
|
-
const total = this.total();
|
|
455
|
-
return {
|
|
456
|
-
first: total === 0 ? 0 : this.offset() + 1,
|
|
457
|
-
last: Math.min(this.offset() + pageSize, total),
|
|
458
|
-
total
|
|
689
|
+
fetch = computed(() => {
|
|
690
|
+
const deskId = this.deskId();
|
|
691
|
+
return async (request) => {
|
|
692
|
+
const page = await this.gateway.requests(deskId, listingOf(request));
|
|
693
|
+
return {
|
|
694
|
+
items: page.items,
|
|
695
|
+
total: Number(page.total)
|
|
696
|
+
};
|
|
459
697
|
};
|
|
460
|
-
}, ...ngDevMode ? [{ debugName: "
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
const value = event.target.value;
|
|
465
|
-
clearTimeout(this.searchTimer);
|
|
466
|
-
this.searchTimer = setTimeout(() => {
|
|
467
|
-
this.text.set(value);
|
|
468
|
-
this.offset.set(0);
|
|
469
|
-
}, searchDelayMs);
|
|
470
|
-
}
|
|
471
|
-
chooseFilter(event) {
|
|
472
|
-
const chosen = statusFilters.find((filter) => filter === event.target.value);
|
|
473
|
-
if (chosen) {
|
|
474
|
-
this.filter.set(chosen);
|
|
475
|
-
this.offset.set(0);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
previous() {
|
|
479
|
-
this.offset.update((offset) => Math.max(0, offset - pageSize));
|
|
698
|
+
}, ...ngDevMode ? [{ debugName: "fetch" }] : /* istanbul ignore next */ []);
|
|
699
|
+
counted(total) {
|
|
700
|
+
this.loadFailed.set(false);
|
|
701
|
+
this.count.set(total);
|
|
480
702
|
}
|
|
481
|
-
|
|
482
|
-
this.
|
|
703
|
+
failed() {
|
|
704
|
+
this.loadFailed.set(true);
|
|
483
705
|
}
|
|
484
706
|
add() {
|
|
485
707
|
this.openDialog({
|
|
486
708
|
deskId: this.deskId(),
|
|
487
709
|
request: null
|
|
488
|
-
}, "service-desk.dialog.addTitle");
|
|
710
|
+
}, "weaver-apps-service-desk.dialog.addTitle");
|
|
489
711
|
}
|
|
490
712
|
actions({ request, x, y }) {
|
|
491
713
|
const closed = isClosed(request.status);
|
|
492
714
|
serviceDeskHost.ui.openMenu([
|
|
493
715
|
{
|
|
494
|
-
label: closed ? "service-desk.actions.view" : "service-desk.actions.edit",
|
|
716
|
+
label: closed ? "weaver-apps-service-desk.actions.view" : "weaver-apps-service-desk.actions.edit",
|
|
495
717
|
icon: closed ? "preview" : "edit",
|
|
496
718
|
run: () => this.open(request)
|
|
497
719
|
},
|
|
498
720
|
...closed ? [] : [{
|
|
499
|
-
label: "service-desk.actions.complete",
|
|
500
|
-
icon:
|
|
721
|
+
label: "weaver-apps-service-desk.actions.complete",
|
|
722
|
+
icon: serviceDeskIconNames.complete,
|
|
501
723
|
run: () => void this.complete(request)
|
|
502
724
|
}, {
|
|
503
|
-
label: "service-desk.actions.cancel",
|
|
504
|
-
icon:
|
|
725
|
+
label: "weaver-apps-service-desk.actions.cancel",
|
|
726
|
+
icon: serviceDeskIconNames.cancel,
|
|
505
727
|
run: () => void this.cancel(request)
|
|
506
728
|
}],
|
|
507
729
|
{
|
|
508
|
-
label: "service-desk.actions.delete",
|
|
730
|
+
label: "weaver-apps-service-desk.actions.delete",
|
|
509
731
|
icon: "trash",
|
|
510
732
|
run: () => void this.remove(request)
|
|
511
733
|
}
|
|
@@ -519,46 +741,49 @@ var DeskPage = class DeskPage {
|
|
|
519
741
|
this.openDialog({
|
|
520
742
|
deskId: this.deskId(),
|
|
521
743
|
request
|
|
522
|
-
}, closed ? "service-desk.dialog.viewTitle" : "service-desk.dialog.editTitle");
|
|
744
|
+
}, closed ? "weaver-apps-service-desk.dialog.viewTitle" : "weaver-apps-service-desk.dialog.editTitle");
|
|
523
745
|
}
|
|
524
746
|
async complete(request) {
|
|
525
|
-
await this.attempt(async () => this.report(await this.gateway.complete(this.deskId(), request.id), "service-desk.complete.done"));
|
|
747
|
+
await this.attempt(async () => this.report(await this.gateway.complete(this.deskId(), request.id), "weaver-apps-service-desk.complete.done"));
|
|
526
748
|
}
|
|
527
749
|
async cancel(request) {
|
|
528
750
|
const reason = await serviceDeskHost.ui.prompt({
|
|
529
|
-
title: "service-desk.cancel.title",
|
|
530
|
-
message: "service-desk.cancel.message",
|
|
531
|
-
confirmLabel: "service-desk.cancel.confirm",
|
|
751
|
+
title: "weaver-apps-service-desk.cancel.title",
|
|
752
|
+
message: "weaver-apps-service-desk.cancel.message",
|
|
753
|
+
confirmLabel: "weaver-apps-service-desk.cancel.confirm",
|
|
532
754
|
tone: "warning"
|
|
533
755
|
});
|
|
534
756
|
if (reason === null) return;
|
|
535
|
-
await this.attempt(async () => this.report(await this.gateway.cancel(this.deskId(), request.id, reason.trim() || null), "service-desk.cancel.done"));
|
|
757
|
+
await this.attempt(async () => this.report(await this.gateway.cancel(this.deskId(), request.id, reason.trim() || null), "weaver-apps-service-desk.cancel.done"));
|
|
536
758
|
}
|
|
537
759
|
async remove(request) {
|
|
538
760
|
if (!await serviceDeskHost.ui.confirm({
|
|
539
|
-
title: "service-desk.delete.title",
|
|
540
|
-
message: "service-desk.delete.message",
|
|
541
|
-
confirmLabel: "service-desk.delete.confirm",
|
|
761
|
+
title: "weaver-apps-service-desk.delete.title",
|
|
762
|
+
message: "weaver-apps-service-desk.delete.message",
|
|
763
|
+
confirmLabel: "weaver-apps-service-desk.delete.confirm",
|
|
542
764
|
tone: "danger"
|
|
543
765
|
})) return;
|
|
544
766
|
await this.attempt(async () => {
|
|
545
767
|
await this.gateway.remove(this.deskId(), request.id);
|
|
546
768
|
serviceDeskHost.ui.toast({
|
|
547
|
-
message: "service-desk.delete.done",
|
|
769
|
+
message: "weaver-apps-service-desk.delete.done",
|
|
548
770
|
kind: "success"
|
|
549
771
|
});
|
|
550
|
-
this.
|
|
772
|
+
this.reload();
|
|
551
773
|
});
|
|
552
774
|
}
|
|
775
|
+
reload() {
|
|
776
|
+
this.grid()?.reload();
|
|
777
|
+
}
|
|
553
778
|
async attempt(work) {
|
|
554
779
|
try {
|
|
555
780
|
await work();
|
|
556
781
|
} catch {
|
|
557
782
|
serviceDeskHost.ui.toast({
|
|
558
|
-
message: "service-desk.errors.save",
|
|
783
|
+
message: "weaver-apps-service-desk.errors.save",
|
|
559
784
|
kind: "error"
|
|
560
785
|
});
|
|
561
|
-
this.
|
|
786
|
+
this.reload();
|
|
562
787
|
}
|
|
563
788
|
}
|
|
564
789
|
openDialog(data, title) {
|
|
@@ -570,20 +795,20 @@ var DeskPage = class DeskPage {
|
|
|
570
795
|
}).closed.then((saved) => {
|
|
571
796
|
if (saved) {
|
|
572
797
|
serviceDeskHost.ui.toast({
|
|
573
|
-
message: "service-desk.dialog.saved",
|
|
798
|
+
message: "weaver-apps-service-desk.dialog.saved",
|
|
574
799
|
kind: "success"
|
|
575
800
|
});
|
|
576
|
-
this.
|
|
801
|
+
this.reload();
|
|
577
802
|
}
|
|
578
803
|
});
|
|
579
804
|
}
|
|
580
805
|
report(outcome, done) {
|
|
581
806
|
const saved = outcome.kind === "saved";
|
|
582
807
|
serviceDeskHost.ui.toast({
|
|
583
|
-
message: saved ? done : "service-desk.errors.save",
|
|
808
|
+
message: saved ? done : "weaver-apps-service-desk.errors.save",
|
|
584
809
|
kind: saved ? "success" : "error"
|
|
585
810
|
});
|
|
586
|
-
this.
|
|
811
|
+
this.reload();
|
|
587
812
|
}
|
|
588
813
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
589
814
|
minVersion: "12.0.0",
|
|
@@ -599,14 +824,25 @@ var DeskPage = class DeskPage {
|
|
|
599
824
|
type: DeskPage,
|
|
600
825
|
isStandalone: true,
|
|
601
826
|
selector: "wa-desk-page",
|
|
827
|
+
viewQueries: [{
|
|
828
|
+
propertyName: "grid",
|
|
829
|
+
first: true,
|
|
830
|
+
predicate: RequestGrid,
|
|
831
|
+
descendants: true,
|
|
832
|
+
isSignal: true
|
|
833
|
+
}],
|
|
602
834
|
ngImport: i0,
|
|
603
|
-
template: "<div class=\"flex h-full flex-col gap-4
|
|
835
|
+
template: "<div class=\"flex h-full flex-col gap-4 p-6\">\n <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <h2 class=\"text-lg font-semibold text-content\">{{ desk.value()?.name ?? ('weaver-apps-service-desk.title' | transloco) }}</h2>\n <div class=\"flex flex-wrap items-center gap-3\">\n @if (count() !== null) {\n <span class=\"text-sm text-content-faint\" data-testid=\"request-count\">{{ 'weaver-apps-service-desk.table.count' | transloco: { count: count() } }}</span>\n }\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"add()\">\n <lw-icon name=\"add\" size=\"1rem\"></lw-icon>\n {{ 'weaver-apps-service-desk.actions.add' | transloco }}\n </button>\n </div>\n </div>\n\n @if (loadFailed()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'weaver-apps-service-desk.errors.load' | transloco }}</p>\n }\n <div class=\"min-h-80 flex-1\">\n <wa-request-grid [fetch]=\"fetch()\" [locale]=\"locale()\" (requestActions)=\"actions($event)\" (counted)=\"counted($event)\" (failed)=\"failed()\" />\n </div>\n</div>\n",
|
|
604
836
|
dependencies: [{
|
|
605
837
|
kind: "component",
|
|
606
|
-
type:
|
|
607
|
-
selector: "wa-request-
|
|
608
|
-
inputs: ["
|
|
609
|
-
outputs: [
|
|
838
|
+
type: RequestGrid,
|
|
839
|
+
selector: "wa-request-grid",
|
|
840
|
+
inputs: ["fetch", "locale"],
|
|
841
|
+
outputs: [
|
|
842
|
+
"requestActions",
|
|
843
|
+
"counted",
|
|
844
|
+
"failed"
|
|
845
|
+
]
|
|
610
846
|
}, {
|
|
611
847
|
kind: "pipe",
|
|
612
848
|
type: TranslocoPipe,
|
|
@@ -624,26 +860,29 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
624
860
|
type: Component,
|
|
625
861
|
args: [{
|
|
626
862
|
selector: "wa-desk-page",
|
|
627
|
-
imports: [TranslocoPipe,
|
|
863
|
+
imports: [TranslocoPipe, RequestGrid],
|
|
628
864
|
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
629
865
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
630
|
-
template: "<div class=\"flex h-full flex-col gap-4
|
|
866
|
+
template: "<div class=\"flex h-full flex-col gap-4 p-6\">\n <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n <h2 class=\"text-lg font-semibold text-content\">{{ desk.value()?.name ?? ('weaver-apps-service-desk.title' | transloco) }}</h2>\n <div class=\"flex flex-wrap items-center gap-3\">\n @if (count() !== null) {\n <span class=\"text-sm text-content-faint\" data-testid=\"request-count\">{{ 'weaver-apps-service-desk.table.count' | transloco: { count: count() } }}</span>\n }\n <button type=\"button\" class=\"lw-btn lw-btn--primary\" (click)=\"add()\">\n <lw-icon name=\"add\" size=\"1rem\"></lw-icon>\n {{ 'weaver-apps-service-desk.actions.add' | transloco }}\n </button>\n </div>\n </div>\n\n @if (loadFailed()) {\n <p class=\"text-sm text-negative\" role=\"alert\">{{ 'weaver-apps-service-desk.errors.load' | transloco }}</p>\n }\n <div class=\"min-h-80 flex-1\">\n <wa-request-grid [fetch]=\"fetch()\" [locale]=\"locale()\" (requestActions)=\"actions($event)\" (counted)=\"counted($event)\" (failed)=\"failed()\" />\n </div>\n</div>\n"
|
|
631
867
|
}]
|
|
632
868
|
}],
|
|
633
|
-
|
|
869
|
+
propDecorators: { grid: [{
|
|
870
|
+
type: i0.ViewChild,
|
|
871
|
+
args: [i0.forwardRef(() => RequestGrid), { isSignal: true }]
|
|
872
|
+
}] }
|
|
634
873
|
});
|
|
635
874
|
const stroke = "fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\"";
|
|
636
875
|
const serviceDeskIcons = {
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
876
|
+
[serviceDeskIconNames.desk]: `<svg viewBox="0 0 24 24" ${stroke}><path d="M4 13.5V7a2.5 2.5 0 0 1 2.5-2.5h11A2.5 2.5 0 0 1 20 7v6.5"/><path d="M3 13.5h5l1.5 2.5h5l1.5-2.5h5V18a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/></svg>`,
|
|
877
|
+
[serviceDeskIconNames.complete]: `<svg viewBox="0 0 24 24" ${stroke}><circle cx="12" cy="12" r="8.5"/><path d="M8.5 12.5l2.5 2.5 4.5-5"/></svg>`,
|
|
878
|
+
[serviceDeskIconNames.cancel]: `<svg viewBox="0 0 24 24" ${stroke}><circle cx="12" cy="12" r="8.5"/><path d="M9 9l6 6M15 9l-6 6"/></svg>`,
|
|
879
|
+
[serviceDeskIconNames.previous]: `<svg viewBox="0 0 24 24" ${stroke}><path d="M15 5l-7 7 7 7"/></svg>`,
|
|
880
|
+
[serviceDeskIconNames.next]: `<svg viewBox="0 0 24 24" ${stroke}><path d="M9 5l7 7-7 7"/></svg>`
|
|
642
881
|
};
|
|
643
882
|
function createServiceDeskPlugin(options = {}) {
|
|
644
883
|
return {
|
|
645
884
|
manifest: {
|
|
646
|
-
id:
|
|
885
|
+
id: serviceDeskPluginId,
|
|
647
886
|
name: "Service desk",
|
|
648
887
|
capabilities: [
|
|
649
888
|
"contributions",
|
|
@@ -655,24 +894,24 @@ function createServiceDeskPlugin(options = {}) {
|
|
|
655
894
|
serviceDeskHost.bind(ctx);
|
|
656
895
|
ctx.contributeIcons(serviceDeskIcons);
|
|
657
896
|
ctx.registerSurface({
|
|
658
|
-
id:
|
|
659
|
-
title: "service-desk.desks.title",
|
|
660
|
-
icon:
|
|
897
|
+
id: serviceDeskContributionIds.desks,
|
|
898
|
+
title: "weaver-apps-service-desk.desks.title",
|
|
899
|
+
icon: serviceDeskIconNames.desk,
|
|
661
900
|
routable: { path: deskListPath },
|
|
662
901
|
component: DeskListPage
|
|
663
902
|
});
|
|
664
903
|
ctx.registerSurface({
|
|
665
|
-
id:
|
|
666
|
-
title: "service-desk.title",
|
|
667
|
-
icon:
|
|
904
|
+
id: serviceDeskContributionIds.desk,
|
|
905
|
+
title: "weaver-apps-service-desk.title",
|
|
906
|
+
icon: serviceDeskIconNames.desk,
|
|
668
907
|
routable: { path: `${deskListPath}/:deskId` },
|
|
669
908
|
component: DeskPage
|
|
670
909
|
});
|
|
671
910
|
if (options.railItem) ctx.registerRailItem({
|
|
672
|
-
id:
|
|
911
|
+
id: serviceDeskContributionIds.rail,
|
|
673
912
|
rail: "primary",
|
|
674
|
-
icon:
|
|
675
|
-
title: "service-desk.desks.title",
|
|
913
|
+
icon: serviceDeskIconNames.desk,
|
|
914
|
+
title: "weaver-apps-service-desk.desks.title",
|
|
676
915
|
run: () => ctx.navigateContent(deskListPath)
|
|
677
916
|
});
|
|
678
917
|
},
|
|
@@ -697,6 +936,16 @@ const getServiceDeskRequestsRaiseUrl = (deskId) => {
|
|
|
697
936
|
const getServiceDeskRequestsListUrl = (deskId, params) => {
|
|
698
937
|
const normalizedParams = new URLSearchParams();
|
|
699
938
|
Object.entries(params || {}).forEach(([key, value]) => {
|
|
939
|
+
if (Array.isArray(value) && [
|
|
940
|
+
"type",
|
|
941
|
+
"status",
|
|
942
|
+
"priority"
|
|
943
|
+
].includes(key)) {
|
|
944
|
+
value.forEach((v) => {
|
|
945
|
+
normalizedParams.append(key, v === null ? "null" : String(v));
|
|
946
|
+
});
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
700
949
|
if (value !== void 0) normalizedParams.append(key, value === null ? "null" : String(value));
|
|
701
950
|
});
|
|
702
951
|
const stringifiedParams = normalizedParams.toString();
|
|
@@ -768,6 +1017,6 @@ function createHttpServiceDeskGateway(options) {
|
|
|
768
1017
|
}
|
|
769
1018
|
};
|
|
770
1019
|
}
|
|
771
|
-
export { SERVICE_DESK_GATEWAY, ServiceDeskGatewayError, createHttpServiceDeskGateway, createServiceDeskPlugin, deskListPath, deskPath, provideServiceDeskGateway, serviceDeskPlugin };
|
|
1020
|
+
export { SERVICE_DESK_GATEWAY, ServiceDeskGatewayError, createHttpServiceDeskGateway, createServiceDeskPlugin, deskListPath, deskPath, provideServiceDeskGateway, serviceDeskContributionIds, serviceDeskPlugin, serviceDeskPluginId };
|
|
772
1021
|
|
|
773
1022
|
//# sourceMappingURL=weaver-apps-service-desk.mjs.map
|