@masterteam/work-center 0.0.1
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.
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.static{position:static}.start{inset-inline-start:var(--spacing)}.flex{display:flex}.grid{display:grid}.h-full{height:100%}.min-h-0{min-height:calc(var(--spacing) * 0)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}@media (min-width:48rem){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (min-width:64rem){.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}}@layer keyframes{@keyframes enter{0%{opacity:var(--p-enter-opacity,1);transform:translate3d(var(--p-enter-translate-x,0), var(--p-enter-translate-y,0), 0) scale3d(var(--p-enter-scale,1), var(--p-enter-scale,1), var(--p-enter-scale,1)) rotate(var(--p-enter-rotate,0))}}@keyframes leave{to{opacity:var(--p-leave-opacity,1);transform:translate3d(var(--p-leave-translate-x,0), var(--p-leave-translate-y,0), 0) scale3d(var(--p-leave-scale,1), var(--p-leave-scale,1), var(--p-leave-scale,1)) rotate(var(--p-leave-rotate,0))}}@keyframes fadein{0%{opacity:0}to{opacity:1}}@keyframes fadeout{0%{opacity:1}to{opacity:0}}@keyframes infinite-scroll{0%{transform:translate(0)}to{transform:translate(-100%)}}@keyframes scalein{0%{opacity:0;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:scaleY(.8)}to{opacity:1;transform:scaleY(1)}}@keyframes slidedown{0%{max-height:0}to{max-height:auto}}@keyframes slideup{0%{max-height:1000px}to{max-height:0}}@keyframes fadeinleft{0%{opacity:0;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:translate(-100%)}to{opacity:1;transform:translate(0%)}}@keyframes fadeoutleft{0%{opacity:1;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:translate(0%)}to{opacity:0;transform:translate(-100%)}}@keyframes fadeinright{0%{opacity:0;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:translate(100%)}to{opacity:1;transform:translate(0%)}}@keyframes fadeoutright{0%{opacity:1;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:translate(0%)}to{opacity:0;transform:translate(100%)}}@keyframes fadeinup{0%{opacity:0;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:translateY(-100%)}to{opacity:1;transform:translateY(0%)}}@keyframes fadeoutup{0%{opacity:1;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:translateY(0%)}to{opacity:0;transform:translateY(-100%)}}@keyframes fadeindown{0%{opacity:0;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:translateY(100%)}to{opacity:1;transform:translateY(0%)}}@keyframes fadeoutdown{0%{opacity:1;transition:transform .12s cubic-bezier(0,0,.2,1),opacity .12s cubic-bezier(0,0,.2,1);transform:translateY(0%)}to{opacity:0;transform:translateY(100%)}}@keyframes width{0%{width:0}to{width:100%}}@keyframes flip{0%{transform:perspective(2000px)rotateX(-100deg)}to{transform:perspective(2000px)rotateX(0)}}@keyframes flipleft{0%{opacity:0;transform:perspective(2000px)rotateY(-100deg)}to{opacity:1;transform:perspective(2000px)rotateY(0)}}@keyframes flipright{0%{opacity:0;transform:perspective(2000px)rotateY(100deg)}to{opacity:1;transform:perspective(2000px)rotateY(0)}}@keyframes flipup{0%{opacity:0;transform:perspective(2000px)rotateX(-100deg)}to{opacity:1;transform:perspective(2000px)rotateX(0)}}@keyframes zoomin{0%{opacity:0;transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomindown{0%{opacity:0;transform:scale3d(.1,.1,.1)translateY(-1000px)}60%{opacity:1;transform:scale3d(.475,.475,.475)translateY(60px)}}@keyframes zoominleft{0%{opacity:0;transform:scale3d(.1,.1,.1)translate(-1000px)}60%{opacity:1;transform:scale3d(.475,.475,.475)translate(10px)}}}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}
|
|
@@ -0,0 +1,805 @@
|
|
|
1
|
+
import { CommonModule } from '@angular/common';
|
|
2
|
+
import * as i0 from '@angular/core';
|
|
3
|
+
import { inject, Injectable, computed, input, output, Component } from '@angular/core';
|
|
4
|
+
import { ClientPage } from '@masterteam/components/client-page';
|
|
5
|
+
import { Page } from '@masterteam/components/page';
|
|
6
|
+
import { PropertyFilterBuilder } from '@masterteam/components/property-filter-builder';
|
|
7
|
+
import { StatisticCard } from '@masterteam/components/statistic-card';
|
|
8
|
+
import { Table } from '@masterteam/components/table';
|
|
9
|
+
import * as i1 from 'primeng/skeleton';
|
|
10
|
+
import { SkeletonModule } from 'primeng/skeleton';
|
|
11
|
+
import { Action, Selector, State, Store, select } from '@ngxs/store';
|
|
12
|
+
import { HttpClient } from '@angular/common/http';
|
|
13
|
+
import { handleApiRequest } from '@masterteam/components';
|
|
14
|
+
import { catchError, EMPTY, map } from 'rxjs';
|
|
15
|
+
|
|
16
|
+
class EnterArea {
|
|
17
|
+
area;
|
|
18
|
+
static type = '[WorkCenter] Enter Area';
|
|
19
|
+
constructor(area) {
|
|
20
|
+
this.area = area;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
class HydrateFromContext {
|
|
24
|
+
area;
|
|
25
|
+
patch;
|
|
26
|
+
static type = '[WorkCenter] Hydrate From Context';
|
|
27
|
+
constructor(area, patch) {
|
|
28
|
+
this.area = area;
|
|
29
|
+
this.patch = patch;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
class SetParams {
|
|
33
|
+
area;
|
|
34
|
+
inputs;
|
|
35
|
+
static type = '[WorkCenter] Set Params';
|
|
36
|
+
constructor(area, inputs) {
|
|
37
|
+
this.area = area;
|
|
38
|
+
this.inputs = inputs;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
class LoadRuntime {
|
|
42
|
+
area;
|
|
43
|
+
reason;
|
|
44
|
+
static type = '[WorkCenter] Load Runtime';
|
|
45
|
+
constructor(area, reason = 'manual') {
|
|
46
|
+
this.area = area;
|
|
47
|
+
this.reason = reason;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
var WorkCenterActionKey;
|
|
52
|
+
(function (WorkCenterActionKey) {
|
|
53
|
+
WorkCenterActionKey["LoadRuntime"] = "loadRuntime";
|
|
54
|
+
})(WorkCenterActionKey || (WorkCenterActionKey = {}));
|
|
55
|
+
const WORK_CENTER_QUERY_VERSION = 1;
|
|
56
|
+
const WORK_CENTER_MAX_PAGE_SIZE = 100;
|
|
57
|
+
const WORK_CENTER_MAX_FILTERS = 20;
|
|
58
|
+
const WORK_CENTER_MAX_SORT = 5;
|
|
59
|
+
|
|
60
|
+
const AREA_COLORS = ['violet', 'blue', 'emerald', 'amber', 'teal'];
|
|
61
|
+
const KPI_COLORS = ['violet', 'blue', 'emerald', 'amber', 'teal'];
|
|
62
|
+
const FILTER_OPERATORS = new Set([
|
|
63
|
+
'Eq',
|
|
64
|
+
'Neq',
|
|
65
|
+
'In',
|
|
66
|
+
'Contains',
|
|
67
|
+
'StartsWith',
|
|
68
|
+
'Gt',
|
|
69
|
+
'Gte',
|
|
70
|
+
'Lt',
|
|
71
|
+
'Lte',
|
|
72
|
+
'Between',
|
|
73
|
+
'IsNull',
|
|
74
|
+
'IsNotNull',
|
|
75
|
+
]);
|
|
76
|
+
function clampPage(value, fallback = 1) {
|
|
77
|
+
if (!Number.isFinite(value))
|
|
78
|
+
return fallback;
|
|
79
|
+
return Math.max(1, Math.floor(value));
|
|
80
|
+
}
|
|
81
|
+
function clampPageSize(value, fallback = 20) {
|
|
82
|
+
if (!Number.isFinite(value))
|
|
83
|
+
return fallback;
|
|
84
|
+
const parsed = Math.floor(value);
|
|
85
|
+
return Math.min(WORK_CENTER_MAX_PAGE_SIZE, Math.max(1, parsed));
|
|
86
|
+
}
|
|
87
|
+
function sanitizeSort(rules) {
|
|
88
|
+
if (!Array.isArray(rules))
|
|
89
|
+
return [];
|
|
90
|
+
return rules
|
|
91
|
+
.filter((rule) => typeof rule?.field === 'string' &&
|
|
92
|
+
rule.field.length > 0 &&
|
|
93
|
+
(rule.dir === 'asc' || rule.dir === 'desc'))
|
|
94
|
+
.slice(0, WORK_CENTER_MAX_SORT);
|
|
95
|
+
}
|
|
96
|
+
function sanitizeFilters(filters) {
|
|
97
|
+
if (!Array.isArray(filters))
|
|
98
|
+
return [];
|
|
99
|
+
return filters
|
|
100
|
+
.filter((filter) => typeof filter?.field === 'string' &&
|
|
101
|
+
filter.field.length > 0 &&
|
|
102
|
+
typeof filter?.op === 'string' &&
|
|
103
|
+
FILTER_OPERATORS.has(filter.op))
|
|
104
|
+
.slice(0, WORK_CENTER_MAX_FILTERS);
|
|
105
|
+
}
|
|
106
|
+
function parseJson(value) {
|
|
107
|
+
if (typeof value !== 'string')
|
|
108
|
+
return value;
|
|
109
|
+
if (!value.trim())
|
|
110
|
+
return null;
|
|
111
|
+
try {
|
|
112
|
+
return JSON.parse(value);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function toOptionalInt(value) {
|
|
119
|
+
if (value === null || value === undefined || value === '')
|
|
120
|
+
return null;
|
|
121
|
+
const parsed = Number(value);
|
|
122
|
+
return Number.isFinite(parsed) ? Math.floor(parsed) : null;
|
|
123
|
+
}
|
|
124
|
+
function toSelectedCardKey(value) {
|
|
125
|
+
if (typeof value !== 'string')
|
|
126
|
+
return null;
|
|
127
|
+
const parsed = value.trim();
|
|
128
|
+
return parsed.length ? parsed : null;
|
|
129
|
+
}
|
|
130
|
+
function parseSortInput(value) {
|
|
131
|
+
const parsed = parseJson(value);
|
|
132
|
+
return Array.isArray(parsed)
|
|
133
|
+
? sanitizeSort(parsed)
|
|
134
|
+
: [];
|
|
135
|
+
}
|
|
136
|
+
function parseFiltersInput(value) {
|
|
137
|
+
const parsed = parseJson(value);
|
|
138
|
+
return Array.isArray(parsed)
|
|
139
|
+
? sanitizeFilters(parsed)
|
|
140
|
+
: [];
|
|
141
|
+
}
|
|
142
|
+
function hasParamValue(value) {
|
|
143
|
+
return value !== null && value !== undefined && value !== '';
|
|
144
|
+
}
|
|
145
|
+
function toLabel$1(value) {
|
|
146
|
+
const segment = value.split('.').pop() ?? value;
|
|
147
|
+
return segment
|
|
148
|
+
.replace(/[_-]/g, ' ')
|
|
149
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
150
|
+
.replace(/\s+/g, ' ')
|
|
151
|
+
.trim()
|
|
152
|
+
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
153
|
+
}
|
|
154
|
+
function toColumnType(key) {
|
|
155
|
+
return key.toLowerCase().includes('date') ? 'date' : 'text';
|
|
156
|
+
}
|
|
157
|
+
function mapViewTypeToColumnType(viewType, key) {
|
|
158
|
+
const normalized = viewType?.toLowerCase();
|
|
159
|
+
if (normalized === 'date' || key.toLowerCase().includes('date')) {
|
|
160
|
+
return 'date';
|
|
161
|
+
}
|
|
162
|
+
return 'text';
|
|
163
|
+
}
|
|
164
|
+
function buildColumnsFromProperties(properties) {
|
|
165
|
+
return properties
|
|
166
|
+
.filter((property) => typeof property?.key === 'string' && property.key.length > 0)
|
|
167
|
+
.map((property) => ({
|
|
168
|
+
key: property.key,
|
|
169
|
+
label: property.name?.display ||
|
|
170
|
+
property.name?.en ||
|
|
171
|
+
property.name?.ar ||
|
|
172
|
+
toLabel$1(property.key),
|
|
173
|
+
type: mapViewTypeToColumnType(property.viewType, property.key),
|
|
174
|
+
}));
|
|
175
|
+
}
|
|
176
|
+
function buildColumns(columnsConfig) {
|
|
177
|
+
const propertyColumns = buildColumnsFromProperties(columnsConfig?.properties ?? []);
|
|
178
|
+
if (propertyColumns.length) {
|
|
179
|
+
return propertyColumns;
|
|
180
|
+
}
|
|
181
|
+
const keys = columnsConfig?.columns?.length ? columnsConfig.columns : [];
|
|
182
|
+
return keys.map((key) => ({
|
|
183
|
+
key,
|
|
184
|
+
label: toLabel$1(key),
|
|
185
|
+
type: toColumnType(key),
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
function buildMenuItems(cards) {
|
|
189
|
+
const mapped = cards.map((card, index) => ({
|
|
190
|
+
key: card.key,
|
|
191
|
+
title: card.name?.display || card.name?.en || card.name?.ar || toLabel$1(card.key),
|
|
192
|
+
subtitle: undefined,
|
|
193
|
+
count: card.count ?? 0,
|
|
194
|
+
color: AREA_COLORS[index % AREA_COLORS.length],
|
|
195
|
+
icon: card.icon ?? 'custom.task',
|
|
196
|
+
isAvailable: card.isAvailable !== false,
|
|
197
|
+
}));
|
|
198
|
+
const available = mapped.filter((card) => card.isAvailable);
|
|
199
|
+
const source = available.length ? available : mapped;
|
|
200
|
+
return source.map((card) => ({
|
|
201
|
+
key: card.key,
|
|
202
|
+
title: card.title,
|
|
203
|
+
subtitle: undefined,
|
|
204
|
+
count: card.count ?? 0,
|
|
205
|
+
color: card.color,
|
|
206
|
+
icon: card.icon ?? 'custom.task',
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
function buildKpis(stats, fallbackIcon) {
|
|
210
|
+
return stats.map((stat, index) => ({
|
|
211
|
+
title: String(stat.count ?? 0),
|
|
212
|
+
subTitle: stat.label.display,
|
|
213
|
+
icon: (fallbackIcon ?? 'custom.task'),
|
|
214
|
+
color: KPI_COLORS[index % KPI_COLORS.length],
|
|
215
|
+
}));
|
|
216
|
+
}
|
|
217
|
+
function createDefaultContext(area) {
|
|
218
|
+
return {
|
|
219
|
+
area,
|
|
220
|
+
templateId: null,
|
|
221
|
+
selectedCardKey: null,
|
|
222
|
+
page: 1,
|
|
223
|
+
pageSize: 20,
|
|
224
|
+
sort: [],
|
|
225
|
+
runtimeFilters: [],
|
|
226
|
+
includeStats: true,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function createDefaultAreaState(area) {
|
|
230
|
+
return {
|
|
231
|
+
context: createDefaultContext(area),
|
|
232
|
+
menuItems: [],
|
|
233
|
+
rows: [],
|
|
234
|
+
columns: [],
|
|
235
|
+
kpis: [],
|
|
236
|
+
runtimeFilterSchema: null,
|
|
237
|
+
totalCount: 0,
|
|
238
|
+
warnings: [],
|
|
239
|
+
lastLoadedAt: null,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const WORK_CENTER_DEFAULT_STATE = {
|
|
243
|
+
activeArea: 'MyInbox',
|
|
244
|
+
byArea: {
|
|
245
|
+
MyInbox: createDefaultAreaState('MyInbox'),
|
|
246
|
+
TasksCenter: createDefaultAreaState('TasksCenter'),
|
|
247
|
+
},
|
|
248
|
+
loadingActive: [],
|
|
249
|
+
errors: {},
|
|
250
|
+
};
|
|
251
|
+
function normalizeContext(context) {
|
|
252
|
+
return {
|
|
253
|
+
...context,
|
|
254
|
+
page: clampPage(context.page, 1),
|
|
255
|
+
pageSize: clampPageSize(context.pageSize, 20),
|
|
256
|
+
sort: sanitizeSort(context.sort),
|
|
257
|
+
runtimeFilters: sanitizeFilters(context.runtimeFilters),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
function buildContextFromInputs(currentContext, area, inputs = {}) {
|
|
261
|
+
const parsedCardKey = toSelectedCardKey(inputs.card);
|
|
262
|
+
const parsedTemplateId = toOptionalInt(inputs.templateId);
|
|
263
|
+
const parsedPage = toOptionalInt(inputs.page);
|
|
264
|
+
const parsedPageSize = toOptionalInt(inputs.pageSize);
|
|
265
|
+
return normalizeContext({
|
|
266
|
+
...currentContext,
|
|
267
|
+
area,
|
|
268
|
+
selectedCardKey: parsedCardKey ?? currentContext.selectedCardKey,
|
|
269
|
+
page: parsedPage ?? currentContext.page,
|
|
270
|
+
pageSize: parsedPageSize ?? currentContext.pageSize,
|
|
271
|
+
templateId: parsedTemplateId ?? currentContext.templateId,
|
|
272
|
+
sort: hasParamValue(inputs.sort)
|
|
273
|
+
? parseSortInput(inputs.sort)
|
|
274
|
+
: currentContext.sort,
|
|
275
|
+
runtimeFilters: hasParamValue(inputs.filters)
|
|
276
|
+
? parseFiltersInput(inputs.filters)
|
|
277
|
+
: currentContext.runtimeFilters,
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
function isSameContext(left, right) {
|
|
281
|
+
return (left.area === right.area &&
|
|
282
|
+
left.templateId === right.templateId &&
|
|
283
|
+
left.selectedCardKey === right.selectedCardKey &&
|
|
284
|
+
left.page === right.page &&
|
|
285
|
+
left.pageSize === right.pageSize &&
|
|
286
|
+
left.includeStats === right.includeStats &&
|
|
287
|
+
JSON.stringify(left.sort) === JSON.stringify(right.sort) &&
|
|
288
|
+
JSON.stringify(left.runtimeFilters) === JSON.stringify(right.runtimeFilters));
|
|
289
|
+
}
|
|
290
|
+
function mapRuntimeResponse(current, response) {
|
|
291
|
+
const selectedCard = response.selectedCard;
|
|
292
|
+
const rows = selectedCard?.items ?? [];
|
|
293
|
+
const menuItems = buildMenuItems(response.cards);
|
|
294
|
+
const requestedCardKey = selectedCard?.key ?? current.context.selectedCardKey ?? null;
|
|
295
|
+
const selectedCardKey = requestedCardKey &&
|
|
296
|
+
response.cards.some((card) => card.key === requestedCardKey)
|
|
297
|
+
? requestedCardKey
|
|
298
|
+
: (menuItems[0]?.key ?? response.cards[0]?.key ?? null);
|
|
299
|
+
const selectedCardFromList = selectedCardKey
|
|
300
|
+
? (response.cards.find((card) => card.key === selectedCardKey) ?? null)
|
|
301
|
+
: null;
|
|
302
|
+
const selectedMenuItem = menuItems.find((item) => item.key === selectedCardKey);
|
|
303
|
+
const columns = buildColumns(selectedCard?.columnsConfig ?? selectedCardFromList?.columnsConfig);
|
|
304
|
+
const kpis = buildKpis(selectedCard?.stats ?? [], selectedMenuItem?.icon ?? null);
|
|
305
|
+
return {
|
|
306
|
+
...current,
|
|
307
|
+
menuItems,
|
|
308
|
+
rows,
|
|
309
|
+
columns,
|
|
310
|
+
kpis,
|
|
311
|
+
runtimeFilterSchema: selectedCard?.runtimeFilterSchema ??
|
|
312
|
+
selectedCardFromList?.runtimeFilterSchema ??
|
|
313
|
+
null,
|
|
314
|
+
totalCount: selectedCard?.pagination.totalCount ?? 0,
|
|
315
|
+
warnings: response.warnings ?? [],
|
|
316
|
+
lastLoadedAt: new Date().toISOString(),
|
|
317
|
+
context: {
|
|
318
|
+
...current.context,
|
|
319
|
+
selectedCardKey,
|
|
320
|
+
page: selectedCard?.pagination.page ?? current.context.page,
|
|
321
|
+
pageSize: selectedCard?.pagination.pageSize ?? current.context.pageSize,
|
|
322
|
+
},
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
327
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
328
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
329
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
330
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
331
|
+
};
|
|
332
|
+
let WorkCenterState = class WorkCenterState {
|
|
333
|
+
http = inject(HttpClient);
|
|
334
|
+
static getState(state) {
|
|
335
|
+
return state;
|
|
336
|
+
}
|
|
337
|
+
static activeArea(state) {
|
|
338
|
+
return state.activeArea;
|
|
339
|
+
}
|
|
340
|
+
static activeSnapshot(activeArea, state) {
|
|
341
|
+
return state.byArea[activeArea];
|
|
342
|
+
}
|
|
343
|
+
static context(snapshot) {
|
|
344
|
+
return snapshot.context;
|
|
345
|
+
}
|
|
346
|
+
static menuItems(snapshot) {
|
|
347
|
+
return snapshot.menuItems;
|
|
348
|
+
}
|
|
349
|
+
static rows(snapshot) {
|
|
350
|
+
return snapshot.rows;
|
|
351
|
+
}
|
|
352
|
+
static columns(snapshot) {
|
|
353
|
+
return snapshot.columns;
|
|
354
|
+
}
|
|
355
|
+
static kpis(snapshot) {
|
|
356
|
+
return snapshot.kpis;
|
|
357
|
+
}
|
|
358
|
+
static runtimeFilterSchema(snapshot) {
|
|
359
|
+
return snapshot.runtimeFilterSchema;
|
|
360
|
+
}
|
|
361
|
+
static totalCount(snapshot) {
|
|
362
|
+
return snapshot.totalCount;
|
|
363
|
+
}
|
|
364
|
+
static warnings(snapshot) {
|
|
365
|
+
return snapshot.warnings;
|
|
366
|
+
}
|
|
367
|
+
static getLoadingActive(state) {
|
|
368
|
+
return state.loadingActive;
|
|
369
|
+
}
|
|
370
|
+
static getErrors(state) {
|
|
371
|
+
return state.errors;
|
|
372
|
+
}
|
|
373
|
+
enterArea(ctx, action) {
|
|
374
|
+
if (ctx.getState().activeArea === action.area)
|
|
375
|
+
return;
|
|
376
|
+
ctx.patchState({ activeArea: action.area });
|
|
377
|
+
}
|
|
378
|
+
hydrateFromContext(ctx, action) {
|
|
379
|
+
const state = ctx.getState();
|
|
380
|
+
const current = state.byArea[action.area];
|
|
381
|
+
const nextContext = normalizeContext({
|
|
382
|
+
...current.context,
|
|
383
|
+
...action.patch,
|
|
384
|
+
area: action.area,
|
|
385
|
+
});
|
|
386
|
+
if (state.activeArea === action.area &&
|
|
387
|
+
isSameContext(current.context, nextContext)) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
ctx.patchState({
|
|
391
|
+
activeArea: action.area,
|
|
392
|
+
byArea: {
|
|
393
|
+
...state.byArea,
|
|
394
|
+
[action.area]: { ...current, context: nextContext },
|
|
395
|
+
},
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
setParams(ctx, action) {
|
|
399
|
+
const state = ctx.getState();
|
|
400
|
+
const current = state.byArea[action.area];
|
|
401
|
+
const nextContext = buildContextFromInputs(current.context, action.area, action.inputs);
|
|
402
|
+
const areaChanged = state.activeArea !== action.area;
|
|
403
|
+
const contextChanged = !isSameContext(current.context, nextContext);
|
|
404
|
+
const runtimeLoading = state.loadingActive.includes(WorkCenterActionKey.LoadRuntime);
|
|
405
|
+
const shouldLoad = areaChanged ||
|
|
406
|
+
contextChanged ||
|
|
407
|
+
(!current.lastLoadedAt && !runtimeLoading);
|
|
408
|
+
if (areaChanged || contextChanged) {
|
|
409
|
+
ctx.patchState({
|
|
410
|
+
activeArea: action.area,
|
|
411
|
+
byArea: {
|
|
412
|
+
...state.byArea,
|
|
413
|
+
[action.area]: { ...current, context: nextContext },
|
|
414
|
+
},
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
if (!shouldLoad)
|
|
418
|
+
return;
|
|
419
|
+
return ctx.dispatch(new LoadRuntime(action.area, 'route-enter'));
|
|
420
|
+
}
|
|
421
|
+
loadRuntime(ctx, action) {
|
|
422
|
+
const state = ctx.getState();
|
|
423
|
+
const areaState = state.byArea[action.area];
|
|
424
|
+
const request = normalizeContext(areaState.context);
|
|
425
|
+
const nextAreaState = {
|
|
426
|
+
...areaState,
|
|
427
|
+
rows: [],
|
|
428
|
+
columns: [],
|
|
429
|
+
kpis: [],
|
|
430
|
+
totalCount: 0,
|
|
431
|
+
};
|
|
432
|
+
ctx.patchState({
|
|
433
|
+
byArea: {
|
|
434
|
+
...state.byArea,
|
|
435
|
+
[action.area]: nextAreaState,
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
return handleApiRequest({
|
|
439
|
+
ctx,
|
|
440
|
+
key: WorkCenterActionKey.LoadRuntime,
|
|
441
|
+
request$: this.getRuntime(request),
|
|
442
|
+
onSuccess: (response, latestState) => {
|
|
443
|
+
const current = latestState.byArea[action.area];
|
|
444
|
+
return {
|
|
445
|
+
byArea: {
|
|
446
|
+
...latestState.byArea,
|
|
447
|
+
[action.area]: mapRuntimeResponse(current, response),
|
|
448
|
+
},
|
|
449
|
+
};
|
|
450
|
+
},
|
|
451
|
+
errorMessage: 'Failed to load Work Center runtime.',
|
|
452
|
+
}).pipe(catchError(() => EMPTY));
|
|
453
|
+
}
|
|
454
|
+
getRuntime(request) {
|
|
455
|
+
return this.http
|
|
456
|
+
.post('workcenter/runtime', request)
|
|
457
|
+
.pipe(map((response) => {
|
|
458
|
+
if (response.code === 1)
|
|
459
|
+
return response.data;
|
|
460
|
+
const fallbackError = 'Failed to load Work Center runtime.';
|
|
461
|
+
const message = response.errors?.message ??
|
|
462
|
+
response.message ??
|
|
463
|
+
fallbackError;
|
|
464
|
+
throw new Error(message);
|
|
465
|
+
}));
|
|
466
|
+
}
|
|
467
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterState, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
468
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterState });
|
|
469
|
+
};
|
|
470
|
+
__decorate([
|
|
471
|
+
Action(EnterArea)
|
|
472
|
+
], WorkCenterState.prototype, "enterArea", null);
|
|
473
|
+
__decorate([
|
|
474
|
+
Action(HydrateFromContext)
|
|
475
|
+
], WorkCenterState.prototype, "hydrateFromContext", null);
|
|
476
|
+
__decorate([
|
|
477
|
+
Action(SetParams)
|
|
478
|
+
], WorkCenterState.prototype, "setParams", null);
|
|
479
|
+
__decorate([
|
|
480
|
+
Action(LoadRuntime)
|
|
481
|
+
], WorkCenterState.prototype, "loadRuntime", null);
|
|
482
|
+
__decorate([
|
|
483
|
+
Selector()
|
|
484
|
+
], WorkCenterState, "getState", null);
|
|
485
|
+
__decorate([
|
|
486
|
+
Selector()
|
|
487
|
+
], WorkCenterState, "activeArea", null);
|
|
488
|
+
__decorate([
|
|
489
|
+
Selector([WorkCenterState.activeArea, WorkCenterState.getState])
|
|
490
|
+
], WorkCenterState, "activeSnapshot", null);
|
|
491
|
+
__decorate([
|
|
492
|
+
Selector([WorkCenterState.activeSnapshot])
|
|
493
|
+
], WorkCenterState, "context", null);
|
|
494
|
+
__decorate([
|
|
495
|
+
Selector([WorkCenterState.activeSnapshot])
|
|
496
|
+
], WorkCenterState, "menuItems", null);
|
|
497
|
+
__decorate([
|
|
498
|
+
Selector([WorkCenterState.activeSnapshot])
|
|
499
|
+
], WorkCenterState, "rows", null);
|
|
500
|
+
__decorate([
|
|
501
|
+
Selector([WorkCenterState.activeSnapshot])
|
|
502
|
+
], WorkCenterState, "columns", null);
|
|
503
|
+
__decorate([
|
|
504
|
+
Selector([WorkCenterState.activeSnapshot])
|
|
505
|
+
], WorkCenterState, "kpis", null);
|
|
506
|
+
__decorate([
|
|
507
|
+
Selector([WorkCenterState.activeSnapshot])
|
|
508
|
+
], WorkCenterState, "runtimeFilterSchema", null);
|
|
509
|
+
__decorate([
|
|
510
|
+
Selector([WorkCenterState.activeSnapshot])
|
|
511
|
+
], WorkCenterState, "totalCount", null);
|
|
512
|
+
__decorate([
|
|
513
|
+
Selector([WorkCenterState.activeSnapshot])
|
|
514
|
+
], WorkCenterState, "warnings", null);
|
|
515
|
+
__decorate([
|
|
516
|
+
Selector()
|
|
517
|
+
], WorkCenterState, "getLoadingActive", null);
|
|
518
|
+
__decorate([
|
|
519
|
+
Selector()
|
|
520
|
+
], WorkCenterState, "getErrors", null);
|
|
521
|
+
WorkCenterState = __decorate([
|
|
522
|
+
State({
|
|
523
|
+
name: 'workCenter',
|
|
524
|
+
defaults: WORK_CENTER_DEFAULT_STATE,
|
|
525
|
+
})
|
|
526
|
+
], WorkCenterState);
|
|
527
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterState, decorators: [{
|
|
528
|
+
type: Injectable
|
|
529
|
+
}], propDecorators: { enterArea: [], hydrateFromContext: [], setParams: [], loadRuntime: [] } });
|
|
530
|
+
|
|
531
|
+
class WorkCenterFacade {
|
|
532
|
+
store = inject(Store);
|
|
533
|
+
activeArea = select(WorkCenterState.activeArea);
|
|
534
|
+
context = select(WorkCenterState.context);
|
|
535
|
+
menuItems = select(WorkCenterState.menuItems);
|
|
536
|
+
rows = select(WorkCenterState.rows);
|
|
537
|
+
columns = select(WorkCenterState.columns);
|
|
538
|
+
kpis = select(WorkCenterState.kpis);
|
|
539
|
+
runtimeFilterSchema = select(WorkCenterState.runtimeFilterSchema);
|
|
540
|
+
totalCount = select(WorkCenterState.totalCount);
|
|
541
|
+
warnings = select(WorkCenterState.warnings);
|
|
542
|
+
loadingActive = select(WorkCenterState.getLoadingActive);
|
|
543
|
+
errors = select(WorkCenterState.getErrors);
|
|
544
|
+
loading = computed(() => this.loadingActive().includes(WorkCenterActionKey.LoadRuntime), ...(ngDevMode ? [{ debugName: "loading" }] : []));
|
|
545
|
+
error = computed(() => this.errors()[WorkCenterActionKey.LoadRuntime] ?? null, ...(ngDevMode ? [{ debugName: "error" }] : []));
|
|
546
|
+
enterArea(area) {
|
|
547
|
+
return this.store.dispatch(new EnterArea(area));
|
|
548
|
+
}
|
|
549
|
+
hydrateContext(area, patch) {
|
|
550
|
+
return this.store.dispatch(new HydrateFromContext(area, patch));
|
|
551
|
+
}
|
|
552
|
+
setParams(area, inputs) {
|
|
553
|
+
return this.store.dispatch(new SetParams(area, inputs));
|
|
554
|
+
}
|
|
555
|
+
selectCardAndLoad(area, selectedCardKey) {
|
|
556
|
+
return this.store.dispatch([
|
|
557
|
+
new HydrateFromContext(area, { selectedCardKey, page: 1 }),
|
|
558
|
+
new LoadRuntime(area, 'menu-change'),
|
|
559
|
+
]);
|
|
560
|
+
}
|
|
561
|
+
applyTableLazyLoadAndLoad(area, event) {
|
|
562
|
+
const context = this.store.selectSnapshot(WorkCenterState.context);
|
|
563
|
+
const patch = {};
|
|
564
|
+
let changed = false;
|
|
565
|
+
const page = this.toPositiveInt(event?.currentPage);
|
|
566
|
+
if (page !== null && page !== context.page) {
|
|
567
|
+
patch.page = page;
|
|
568
|
+
changed = true;
|
|
569
|
+
}
|
|
570
|
+
const pageSize = this.toPositiveInt(event?.pageSize);
|
|
571
|
+
if (pageSize !== null) {
|
|
572
|
+
const normalizedPageSize = Math.min(WORK_CENTER_MAX_PAGE_SIZE, Math.max(1, pageSize));
|
|
573
|
+
if (normalizedPageSize !== context.pageSize) {
|
|
574
|
+
patch.pageSize = normalizedPageSize;
|
|
575
|
+
changed = true;
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
const sort = this.toSortFromLazyEvent(event);
|
|
579
|
+
if (sort && !this.isSameSort(sort, context.sort)) {
|
|
580
|
+
patch.sort = sort;
|
|
581
|
+
changed = true;
|
|
582
|
+
}
|
|
583
|
+
if (!changed) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
return this.store.dispatch([
|
|
587
|
+
new HydrateFromContext(area, patch),
|
|
588
|
+
new LoadRuntime(area, 'table-lazy'),
|
|
589
|
+
]);
|
|
590
|
+
}
|
|
591
|
+
applyRuntimeFiltersAndLoad(area, runtimeFilters) {
|
|
592
|
+
return this.store.dispatch([
|
|
593
|
+
new HydrateFromContext(area, { runtimeFilters, page: 1 }),
|
|
594
|
+
new LoadRuntime(area, 'filters-change'),
|
|
595
|
+
]);
|
|
596
|
+
}
|
|
597
|
+
loadRuntime(area, reason = 'manual') {
|
|
598
|
+
return this.store.dispatch(new LoadRuntime(area, reason));
|
|
599
|
+
}
|
|
600
|
+
toPositiveInt(value) {
|
|
601
|
+
const parsed = Number(value);
|
|
602
|
+
if (!Number.isFinite(parsed)) {
|
|
603
|
+
return null;
|
|
604
|
+
}
|
|
605
|
+
return Math.max(1, Math.floor(parsed));
|
|
606
|
+
}
|
|
607
|
+
toSortFromLazyEvent(event) {
|
|
608
|
+
const sortField = event?.sortField;
|
|
609
|
+
if (typeof sortField !== 'string' || !sortField.length) {
|
|
610
|
+
return null;
|
|
611
|
+
}
|
|
612
|
+
return [
|
|
613
|
+
{
|
|
614
|
+
field: sortField,
|
|
615
|
+
dir: event?.sortOrder === -1 ? 'desc' : 'asc',
|
|
616
|
+
},
|
|
617
|
+
];
|
|
618
|
+
}
|
|
619
|
+
isSameSort(left, right) {
|
|
620
|
+
const leftValue = left ?? [];
|
|
621
|
+
const rightValue = right ?? [];
|
|
622
|
+
if (leftValue.length !== rightValue.length) {
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
return leftValue.every((rule, index) => rule.field === rightValue[index]?.field &&
|
|
626
|
+
rule.dir === rightValue[index]?.dir);
|
|
627
|
+
}
|
|
628
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterFacade, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
629
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterFacade, providedIn: 'root' });
|
|
630
|
+
}
|
|
631
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterFacade, decorators: [{
|
|
632
|
+
type: Injectable,
|
|
633
|
+
args: [{
|
|
634
|
+
providedIn: 'root',
|
|
635
|
+
}]
|
|
636
|
+
}] });
|
|
637
|
+
|
|
638
|
+
const OPERATOR_LABELS = {
|
|
639
|
+
Eq: 'Equals',
|
|
640
|
+
Neq: 'Not equal',
|
|
641
|
+
In: 'In',
|
|
642
|
+
Contains: 'Contains',
|
|
643
|
+
StartsWith: 'Starts with',
|
|
644
|
+
Gt: 'Greater than',
|
|
645
|
+
Gte: 'Greater than or equal',
|
|
646
|
+
Lt: 'Less than',
|
|
647
|
+
Lte: 'Less than or equal',
|
|
648
|
+
Between: 'Between',
|
|
649
|
+
IsNull: 'Is empty',
|
|
650
|
+
IsNotNull: 'Is not empty',
|
|
651
|
+
};
|
|
652
|
+
const OPERATOR_VALUE_MODE = {
|
|
653
|
+
In: 'multi',
|
|
654
|
+
Between: 'range',
|
|
655
|
+
IsNull: 'none',
|
|
656
|
+
IsNotNull: 'none',
|
|
657
|
+
};
|
|
658
|
+
function toLabel(value) {
|
|
659
|
+
const normalized = value.split('.').pop() ?? value;
|
|
660
|
+
return normalized
|
|
661
|
+
.replace(/[_-]/g, ' ')
|
|
662
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
663
|
+
.trim()
|
|
664
|
+
.replace(/\b\w/g, (char) => char.toUpperCase());
|
|
665
|
+
}
|
|
666
|
+
function columnTypeToViewType(type) {
|
|
667
|
+
if (type === 'date')
|
|
668
|
+
return 'Date';
|
|
669
|
+
return undefined;
|
|
670
|
+
}
|
|
671
|
+
function mapAllowedFields(schema) {
|
|
672
|
+
const properties = schema.properties ?? [];
|
|
673
|
+
const fromProperties = properties
|
|
674
|
+
.filter((property) => typeof property?.key === 'string' && property.key.length > 0)
|
|
675
|
+
.map((property) => ({
|
|
676
|
+
key: property.key,
|
|
677
|
+
label: property.name?.display ||
|
|
678
|
+
property.name?.en ||
|
|
679
|
+
property.name?.ar ||
|
|
680
|
+
toLabel(property.key),
|
|
681
|
+
viewType: property.viewType,
|
|
682
|
+
}));
|
|
683
|
+
if (fromProperties.length) {
|
|
684
|
+
return fromProperties;
|
|
685
|
+
}
|
|
686
|
+
return (schema.allowedFields ?? []).map((field) => ({
|
|
687
|
+
key: field,
|
|
688
|
+
label: toLabel(field),
|
|
689
|
+
}));
|
|
690
|
+
}
|
|
691
|
+
function mapAllowedOperators(schema) {
|
|
692
|
+
const options = [];
|
|
693
|
+
for (const operator of schema.allowedOperators ?? []) {
|
|
694
|
+
if (typeof operator === 'string') {
|
|
695
|
+
options.push({
|
|
696
|
+
key: operator,
|
|
697
|
+
label: OPERATOR_LABELS[operator] ?? toLabel(operator),
|
|
698
|
+
valueMode: OPERATOR_VALUE_MODE[operator] ?? 'single',
|
|
699
|
+
});
|
|
700
|
+
continue;
|
|
701
|
+
}
|
|
702
|
+
const key = operator?.value;
|
|
703
|
+
if (!key) {
|
|
704
|
+
continue;
|
|
705
|
+
}
|
|
706
|
+
options.push({
|
|
707
|
+
key,
|
|
708
|
+
label: operator.display?.display ||
|
|
709
|
+
operator.display?.en ||
|
|
710
|
+
operator.display?.ar ||
|
|
711
|
+
OPERATOR_LABELS[key] ||
|
|
712
|
+
toLabel(key),
|
|
713
|
+
valueMode: OPERATOR_VALUE_MODE[key] ?? 'single',
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
return options;
|
|
717
|
+
}
|
|
718
|
+
class WorkCenterPage {
|
|
719
|
+
facade = inject(WorkCenterFacade);
|
|
720
|
+
area = input('MyInbox', ...(ngDevMode ? [{ debugName: "area" }] : []));
|
|
721
|
+
pageTitle = input('Work Center', ...(ngDevMode ? [{ debugName: "pageTitle" }] : []));
|
|
722
|
+
menuIcon = input('communication.inbox-01', ...(ngDevMode ? [{ debugName: "menuIcon" }] : []));
|
|
723
|
+
runtimeFiltersChanged = output();
|
|
724
|
+
context = this.facade.context;
|
|
725
|
+
menuItems = this.facade.menuItems;
|
|
726
|
+
rows = this.facade.rows;
|
|
727
|
+
columns = this.facade.columns;
|
|
728
|
+
kpis = this.facade.kpis;
|
|
729
|
+
runtimeFilterSchema = this.facade.runtimeFilterSchema;
|
|
730
|
+
totalCount = this.facade.totalCount;
|
|
731
|
+
loading = this.facade.loading;
|
|
732
|
+
tableCurrentPage = computed(() => Math.max((this.context().page ?? 1) - 1, 0), ...(ngDevMode ? [{ debugName: "tableCurrentPage" }] : []));
|
|
733
|
+
tableFirst = computed(() => this.tableCurrentPage() * (this.context().pageSize || 20), ...(ngDevMode ? [{ debugName: "tableFirst" }] : []));
|
|
734
|
+
propertyFilterSchema = computed(() => {
|
|
735
|
+
const schema = this.runtimeFilterSchema();
|
|
736
|
+
if (schema) {
|
|
737
|
+
const allowedFields = mapAllowedFields(schema);
|
|
738
|
+
const allowedOperators = mapAllowedOperators(schema);
|
|
739
|
+
if (allowedFields.length && allowedOperators.length) {
|
|
740
|
+
return { allowedFields, allowedOperators };
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
const fallbackFields = this.columns()
|
|
744
|
+
.filter((column) => typeof column?.key === 'string' && column.key.length > 0)
|
|
745
|
+
.map((column) => ({
|
|
746
|
+
key: column.key,
|
|
747
|
+
label: column.label || toLabel(column.key),
|
|
748
|
+
viewType: columnTypeToViewType(column.type),
|
|
749
|
+
}));
|
|
750
|
+
if (!fallbackFields.length) {
|
|
751
|
+
return null;
|
|
752
|
+
}
|
|
753
|
+
const fallbackOperators = Object.keys(OPERATOR_LABELS).map((key) => ({
|
|
754
|
+
key,
|
|
755
|
+
label: OPERATOR_LABELS[key] ?? toLabel(key),
|
|
756
|
+
valueMode: OPERATOR_VALUE_MODE[key] ?? 'single',
|
|
757
|
+
}));
|
|
758
|
+
return {
|
|
759
|
+
allowedFields: fallbackFields,
|
|
760
|
+
allowedOperators: fallbackOperators,
|
|
761
|
+
};
|
|
762
|
+
}, ...(ngDevMode ? [{ debugName: "propertyFilterSchema" }] : []));
|
|
763
|
+
onMenuItemClick(item) {
|
|
764
|
+
this.facade.selectCardAndLoad(this.area(), item.key);
|
|
765
|
+
}
|
|
766
|
+
onLazyLoad(event) {
|
|
767
|
+
this.facade.applyTableLazyLoadAndLoad(this.area(), event);
|
|
768
|
+
}
|
|
769
|
+
onRuntimeFiltersApplied(filters) {
|
|
770
|
+
this.runtimeFiltersChanged.emit(filters.map((filter) => ({
|
|
771
|
+
field: filter.field,
|
|
772
|
+
op: filter.op,
|
|
773
|
+
value: filter.value,
|
|
774
|
+
values: filter.values,
|
|
775
|
+
from: filter.from,
|
|
776
|
+
to: filter.to,
|
|
777
|
+
})));
|
|
778
|
+
}
|
|
779
|
+
onRuntimeFiltersCleared() {
|
|
780
|
+
this.runtimeFiltersChanged.emit([]);
|
|
781
|
+
}
|
|
782
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterPage, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
783
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: WorkCenterPage, isStandalone: true, selector: "mt-work-center-page", inputs: { area: { classPropertyName: "area", publicName: "area", isSignal: true, isRequired: false, transformFunction: null }, pageTitle: { classPropertyName: "pageTitle", publicName: "pageTitle", isSignal: true, isRequired: false, transformFunction: null }, menuIcon: { classPropertyName: "menuIcon", publicName: "menuIcon", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { runtimeFiltersChanged: "runtimeFiltersChanged" }, ngImport: i0, template: "<mt-page [title]=\"pageTitle()\" [avatarIcon]=\"menuIcon()\">\r\n <div class=\"h-full min-h-0\">\r\n <mt-client-page\r\n [menuIcon]=\"menuIcon()\"\r\n [menuTitle]=\"pageTitle()\"\r\n [menuItems]=\"menuItems()\"\r\n [menuItemsLoading]=\"loading() && !menuItems().length\"\r\n [activeItem]=\"context().selectedCardKey ?? undefined\"\r\n (menuItemClick)=\"onMenuItemClick($event)\"\r\n >\r\n <ng-template #headerClientPageEnd>\r\n <mt-property-filter-builder\r\n [schema]=\"propertyFilterSchema()\"\r\n [filters]=\"context().runtimeFilters\"\r\n (applied)=\"onRuntimeFiltersApplied($event)\"\r\n (cleared)=\"onRuntimeFiltersCleared()\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n @if (loading()) {\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n @for (_ of [1, 2, 3, 4]; track $index) {\r\n <p-skeleton height=\"6.5rem\" borderRadius=\"1rem\" />\r\n }\r\n </div>\r\n } @else if (kpis().length) {\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n @for (kpi of kpis(); track $index) {\r\n <mt-statistic-card [data]=\"kpi\" />\r\n }\r\n </div>\r\n }\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [lazy]=\"true\"\r\n [loading]=\"loading()\"\r\n [lazyTotalRecords]=\"totalCount()\"\r\n [showFilters]=\"false\"\r\n [generalSearch]=\"false\"\r\n [pageSize]=\"context().pageSize\"\r\n [currentPage]=\"tableCurrentPage()\"\r\n [first]=\"tableFirst()\"\r\n (lazyLoad)=\"onLazyLoad($event)\"\r\n />\r\n </div>\r\n </mt-client-page>\r\n </div>\r\n</mt-page>\r\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ClientPage, selector: "mt-client-page", inputs: ["menuIcon", "menuTitle", "menuItems", "menuItemsLoading", "activeItem", "collapsed"], outputs: ["collapsedChange", "menuItemClick"] }, { kind: "component", type: Page, selector: "mt-page", inputs: ["backButton", "backButtonIcon", "avatarIcon", "avatarStyle", "avatarShape", "title", "tabs", "activeTab", "contentClass", "contentId"], outputs: ["backButtonClick", "tabChange"] }, { kind: "component", type: PropertyFilterBuilder, selector: "mt-property-filter-builder", inputs: ["schema", "filters", "title", "buttonLabel", "disabled"], outputs: ["filtersChange", "applied", "cleared"] }, { kind: "component", type: StatisticCard, selector: "mt-statistic-card", inputs: ["data"] }, { kind: "component", type: Table, selector: "mt-table", inputs: ["filters", "data", "columns", "rowActions", "size", "showGridlines", "stripedRows", "selectableRows", "generalSearch", "showFilters", "loading", "updating", "lazy", "lazyTotalRecords", "reorderableColumns", "reorderableRows", "dataKey", "exportable", "exportFilename", "tabs", "tabsOptionLabel", "tabsOptionValue", "activeTab", "actions", "paginatorPosition", "pageSize", "currentPage", "first", "filterTerm"], outputs: ["selectionChange", "cellChange", "lazyLoad", "columnReorder", "rowReorder", "filtersChange", "activeTabChange", "onTabChange", "pageSizeChange", "currentPageChange", "firstChange", "filterTermChange"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }] });
|
|
784
|
+
}
|
|
785
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: WorkCenterPage, decorators: [{
|
|
786
|
+
type: Component,
|
|
787
|
+
args: [{ selector: 'mt-work-center-page', standalone: true, imports: [
|
|
788
|
+
CommonModule,
|
|
789
|
+
ClientPage,
|
|
790
|
+
Page,
|
|
791
|
+
PropertyFilterBuilder,
|
|
792
|
+
StatisticCard,
|
|
793
|
+
Table,
|
|
794
|
+
SkeletonModule,
|
|
795
|
+
], template: "<mt-page [title]=\"pageTitle()\" [avatarIcon]=\"menuIcon()\">\r\n <div class=\"h-full min-h-0\">\r\n <mt-client-page\r\n [menuIcon]=\"menuIcon()\"\r\n [menuTitle]=\"pageTitle()\"\r\n [menuItems]=\"menuItems()\"\r\n [menuItemsLoading]=\"loading() && !menuItems().length\"\r\n [activeItem]=\"context().selectedCardKey ?? undefined\"\r\n (menuItemClick)=\"onMenuItemClick($event)\"\r\n >\r\n <ng-template #headerClientPageEnd>\r\n <mt-property-filter-builder\r\n [schema]=\"propertyFilterSchema()\"\r\n [filters]=\"context().runtimeFilters\"\r\n (applied)=\"onRuntimeFiltersApplied($event)\"\r\n (cleared)=\"onRuntimeFiltersCleared()\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n @if (loading()) {\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n @for (_ of [1, 2, 3, 4]; track $index) {\r\n <p-skeleton height=\"6.5rem\" borderRadius=\"1rem\" />\r\n }\r\n </div>\r\n } @else if (kpis().length) {\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n @for (kpi of kpis(); track $index) {\r\n <mt-statistic-card [data]=\"kpi\" />\r\n }\r\n </div>\r\n }\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [lazy]=\"true\"\r\n [loading]=\"loading()\"\r\n [lazyTotalRecords]=\"totalCount()\"\r\n [showFilters]=\"false\"\r\n [generalSearch]=\"false\"\r\n [pageSize]=\"context().pageSize\"\r\n [currentPage]=\"tableCurrentPage()\"\r\n [first]=\"tableFirst()\"\r\n (lazyLoad)=\"onLazyLoad($event)\"\r\n />\r\n </div>\r\n </mt-client-page>\r\n </div>\r\n</mt-page>\r\n" }]
|
|
796
|
+
}], propDecorators: { area: [{ type: i0.Input, args: [{ isSignal: true, alias: "area", required: false }] }], pageTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageTitle", required: false }] }], menuIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "menuIcon", required: false }] }], runtimeFiltersChanged: [{ type: i0.Output, args: ["runtimeFiltersChanged"] }] } });
|
|
797
|
+
|
|
798
|
+
const APP_STATES = [WorkCenterState];
|
|
799
|
+
|
|
800
|
+
/**
|
|
801
|
+
* Generated bundle index. Do not edit.
|
|
802
|
+
*/
|
|
803
|
+
|
|
804
|
+
export { APP_STATES, EnterArea, HydrateFromContext, LoadRuntime, SetParams, WORK_CENTER_MAX_FILTERS, WORK_CENTER_MAX_PAGE_SIZE, WORK_CENTER_MAX_SORT, WORK_CENTER_QUERY_VERSION, WorkCenterActionKey, WorkCenterFacade, WorkCenterPage, WorkCenterState };
|
|
805
|
+
//# sourceMappingURL=masterteam-work-center.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"masterteam-work-center.mjs","sources":["../../../../packages/masterteam/work-center/src/store/work-center/work-center.actions.ts","../../../../packages/masterteam/work-center/src/store/work-center/work-center.model.ts","../../../../packages/masterteam/work-center/src/store/work-center/work-center.state.helpers.ts","../../../../packages/masterteam/work-center/src/store/work-center/work-center.state.ts","../../../../packages/masterteam/work-center/src/store/work-center/work-center.facade.ts","../../../../packages/masterteam/work-center/src/lib/work-center-page/work-center-page.ts","../../../../packages/masterteam/work-center/src/lib/work-center-page/work-center-page.html","../../../../packages/masterteam/work-center/src/store/app.state.ts","../../../../packages/masterteam/work-center/src/masterteam-work-center.ts"],"sourcesContent":["import {\r\n WorkCenterArea,\r\n WorkCenterBootstrapInputs,\r\n WorkCenterHydratePatch,\r\n WorkCenterLoadReason,\r\n} from './work-center.model';\r\n\r\nexport class EnterArea {\r\n static readonly type = '[WorkCenter] Enter Area';\r\n\r\n constructor(public area: WorkCenterArea) {}\r\n}\r\n\r\nexport class HydrateFromContext {\r\n static readonly type = '[WorkCenter] Hydrate From Context';\r\n\r\n constructor(\r\n public area: WorkCenterArea,\r\n public patch: WorkCenterHydratePatch,\r\n ) {}\r\n}\r\n\r\nexport class SetParams {\r\n static readonly type = '[WorkCenter] Set Params';\r\n\r\n constructor(\r\n public area: WorkCenterArea,\r\n public inputs: WorkCenterBootstrapInputs,\r\n ) {}\r\n}\r\n\r\nexport class LoadRuntime {\r\n static readonly type = '[WorkCenter] Load Runtime';\r\n\r\n constructor(\r\n public area: WorkCenterArea,\r\n public reason: WorkCenterLoadReason = 'manual',\r\n ) {}\r\n}\r\n","import type { LoadingStateShape } from '@masterteam/components';\r\nimport { ClientPageMenuItem } from '@masterteam/components/client-page-menu';\r\nimport { StatisticCardData } from '@masterteam/components/statistic-card';\r\nimport { ColumnDef } from '@masterteam/components/table';\r\n\r\nexport type WorkCenterArea = 'MyInbox' | 'TasksCenter';\r\n\r\nexport enum WorkCenterActionKey {\r\n LoadRuntime = 'loadRuntime',\r\n}\r\n\r\nexport const WORK_CENTER_QUERY_VERSION = 1;\r\nexport const WORK_CENTER_MAX_PAGE_SIZE = 100;\r\nexport const WORK_CENTER_MAX_FILTERS = 20;\r\nexport const WORK_CENTER_MAX_SORT = 5;\r\n\r\nexport interface ApiEnvelope<T> {\r\n endpoint: string | null;\r\n status: number;\r\n code: 1 | 2;\r\n locale: string | null;\r\n message: string | null;\r\n errors: unknown;\r\n data: T;\r\n cacheSession: string | null;\r\n}\r\n\r\nexport interface TranslatableDto {\r\n display: string;\r\n en: string;\r\n ar: string;\r\n}\r\n\r\nexport interface WorkCenterSortRule {\r\n field: string;\r\n dir: 'asc' | 'desc';\r\n}\r\n\r\nexport type WorkCenterFilterOperator =\r\n | 'Eq'\r\n | 'Neq'\r\n | 'In'\r\n | 'Contains'\r\n | 'StartsWith'\r\n | 'Gt'\r\n | 'Gte'\r\n | 'Lt'\r\n | 'Lte'\r\n | 'Between'\r\n | 'IsNull'\r\n | 'IsNotNull';\r\n\r\nexport interface WorkCenterFilterRule {\r\n field: string;\r\n op: WorkCenterFilterOperator;\r\n value?: unknown;\r\n values?: unknown[];\r\n from?: unknown;\r\n to?: unknown;\r\n}\r\n\r\nexport interface WorkCenterRuntimeProperty {\r\n id?: number;\r\n key: string;\r\n normalizedKey?: string;\r\n name?: TranslatableDto;\r\n description?: TranslatableDto;\r\n viewType?: string;\r\n}\r\n\r\nexport interface WorkCenterRuntimeOperatorOption {\r\n value: WorkCenterFilterOperator;\r\n display?: TranslatableDto;\r\n}\r\n\r\nexport interface WorkCenterRuntimeFilterSchema {\r\n properties?: WorkCenterRuntimeProperty[];\r\n allowedFields?: string[];\r\n allowedOperators: Array<\r\n WorkCenterFilterOperator | WorkCenterRuntimeOperatorOption\r\n >;\r\n}\r\n\r\nexport interface WorkCenterColumnsConfig {\r\n columns?: string[];\r\n properties?: WorkCenterRuntimeProperty[];\r\n}\r\n\r\nexport interface WorkCenterRuntimeRequest {\r\n area: WorkCenterArea;\r\n templateId?: number | null;\r\n selectedCardKey?: string | null;\r\n page: number;\r\n pageSize: number;\r\n sort: WorkCenterSortRule[];\r\n runtimeFilters: WorkCenterFilterRule[];\r\n includeStats: boolean;\r\n}\r\n\r\nexport interface WorkCenterRuntimeCard {\r\n key: string;\r\n name: TranslatableDto;\r\n icon: string | null;\r\n urlTemplate?: string | null;\r\n runtimeFilterSchema?: WorkCenterRuntimeFilterSchema | null;\r\n columnsConfig?: WorkCenterColumnsConfig | null;\r\n count: number;\r\n isAvailable: boolean;\r\n}\r\n\r\nexport interface WorkCenterRuntimeStatsItem {\r\n key: string;\r\n label: TranslatableDto;\r\n count: number;\r\n}\r\n\r\nexport interface WorkCenterRuntimePagination {\r\n page: number;\r\n pageSize: number;\r\n totalCount: number;\r\n}\r\n\r\nexport interface WorkCenterRuntimeSelectedCard {\r\n key: string;\r\n pagination: WorkCenterRuntimePagination;\r\n stats: WorkCenterRuntimeStatsItem[];\r\n items: Record<string, unknown>[];\r\n runtimeFilterSchema?: WorkCenterRuntimeFilterSchema | null;\r\n columnsConfig?: WorkCenterColumnsConfig | null;\r\n}\r\n\r\nexport interface WorkCenterRuntimeWarningDto {\r\n code: string;\r\n message: string;\r\n cardKey: string | null;\r\n source: string | null;\r\n}\r\n\r\nexport interface WorkCenterRuntimeResponseData {\r\n area: WorkCenterArea;\r\n cards: WorkCenterRuntimeCard[];\r\n selectedCard: WorkCenterRuntimeSelectedCard | null;\r\n warnings: WorkCenterRuntimeWarningDto[];\r\n}\r\n\r\nexport interface WorkCenterContext {\r\n area: WorkCenterArea;\r\n templateId: number | null;\r\n selectedCardKey: string | null;\r\n page: number;\r\n pageSize: number;\r\n sort: WorkCenterSortRule[];\r\n runtimeFilters: WorkCenterFilterRule[];\r\n includeStats: boolean;\r\n}\r\n\r\nexport interface WorkCenterAreaState {\r\n context: WorkCenterContext;\r\n menuItems: ClientPageMenuItem[];\r\n rows: Record<string, unknown>[];\r\n columns: ColumnDef[];\r\n kpis: StatisticCardData[];\r\n runtimeFilterSchema: WorkCenterRuntimeFilterSchema | null;\r\n totalCount: number;\r\n warnings: WorkCenterRuntimeWarningDto[];\r\n lastLoadedAt: string | null;\r\n}\r\n\r\nexport interface WorkCenterStateModel extends LoadingStateShape<WorkCenterActionKey> {\r\n activeArea: WorkCenterArea;\r\n byArea: Record<WorkCenterArea, WorkCenterAreaState>;\r\n}\r\n\r\nexport interface WorkCenterHydratePatch {\r\n selectedCardKey?: string | null;\r\n page?: number;\r\n pageSize?: number;\r\n templateId?: number | null;\r\n sort?: WorkCenterSortRule[];\r\n runtimeFilters?: WorkCenterFilterRule[];\r\n}\r\n\r\nexport interface WorkCenterBootstrapInputs {\r\n card?: unknown;\r\n page?: unknown;\r\n pageSize?: unknown;\r\n templateId?: unknown;\r\n sort?: unknown;\r\n filters?: unknown;\r\n}\r\n\r\nexport type WorkCenterLoadReason =\r\n | 'route-enter'\r\n | 'menu-change'\r\n | 'filters-change'\r\n | 'table-lazy'\r\n | 'refresh'\r\n | 'manual';\r\n","import { ClientPageMenuItem } from '@masterteam/components/client-page-menu';\r\nimport { StatisticCardData } from '@masterteam/components/statistic-card';\r\nimport { ColumnDef } from '@masterteam/components/table';\r\n\r\nimport {\r\n WorkCenterArea,\r\n WorkCenterAreaState,\r\n WorkCenterBootstrapInputs,\r\n WorkCenterColumnsConfig,\r\n WorkCenterContext,\r\n WorkCenterFilterOperator,\r\n WorkCenterFilterRule,\r\n WorkCenterRuntimeProperty,\r\n WorkCenterRuntimeCard,\r\n WorkCenterRuntimeResponseData,\r\n WorkCenterRuntimeStatsItem,\r\n WorkCenterSortRule,\r\n WorkCenterStateModel,\r\n WORK_CENTER_MAX_FILTERS,\r\n WORK_CENTER_MAX_PAGE_SIZE,\r\n WORK_CENTER_MAX_SORT,\r\n} from './work-center.model';\r\n\r\nconst AREA_COLORS = ['violet', 'blue', 'emerald', 'amber', 'teal'];\r\nconst KPI_COLORS = ['violet', 'blue', 'emerald', 'amber', 'teal'];\r\n\r\nconst FILTER_OPERATORS: Set<WorkCenterFilterOperator> = new Set([\r\n 'Eq',\r\n 'Neq',\r\n 'In',\r\n 'Contains',\r\n 'StartsWith',\r\n 'Gt',\r\n 'Gte',\r\n 'Lt',\r\n 'Lte',\r\n 'Between',\r\n 'IsNull',\r\n 'IsNotNull',\r\n]);\r\n\r\nfunction clampPage(value: number | undefined, fallback = 1): number {\r\n if (!Number.isFinite(value)) return fallback;\r\n return Math.max(1, Math.floor(value as number));\r\n}\r\n\r\nfunction clampPageSize(value: number | undefined, fallback = 20): number {\r\n if (!Number.isFinite(value)) return fallback;\r\n const parsed = Math.floor(value as number);\r\n return Math.min(WORK_CENTER_MAX_PAGE_SIZE, Math.max(1, parsed));\r\n}\r\n\r\nfunction sanitizeSort(\r\n rules: WorkCenterSortRule[] | undefined,\r\n): WorkCenterSortRule[] {\r\n if (!Array.isArray(rules)) return [];\r\n return rules\r\n .filter(\r\n (rule): rule is WorkCenterSortRule =>\r\n typeof rule?.field === 'string' &&\r\n rule.field.length > 0 &&\r\n (rule.dir === 'asc' || rule.dir === 'desc'),\r\n )\r\n .slice(0, WORK_CENTER_MAX_SORT);\r\n}\r\n\r\nfunction sanitizeFilters(\r\n filters: WorkCenterFilterRule[] | undefined,\r\n): WorkCenterFilterRule[] {\r\n if (!Array.isArray(filters)) return [];\r\n\r\n return filters\r\n .filter(\r\n (filter): filter is WorkCenterFilterRule =>\r\n typeof filter?.field === 'string' &&\r\n filter.field.length > 0 &&\r\n typeof filter?.op === 'string' &&\r\n FILTER_OPERATORS.has(filter.op),\r\n )\r\n .slice(0, WORK_CENTER_MAX_FILTERS);\r\n}\r\n\r\nfunction parseJson(value: unknown): unknown {\r\n if (typeof value !== 'string') return value;\r\n if (!value.trim()) return null;\r\n\r\n try {\r\n return JSON.parse(value);\r\n } catch {\r\n return null;\r\n }\r\n}\r\n\r\nfunction toOptionalInt(value: unknown): number | null {\r\n if (value === null || value === undefined || value === '') return null;\r\n const parsed = Number(value);\r\n return Number.isFinite(parsed) ? Math.floor(parsed) : null;\r\n}\r\n\r\nfunction toSelectedCardKey(value: unknown): string | null {\r\n if (typeof value !== 'string') return null;\r\n const parsed = value.trim();\r\n return parsed.length ? parsed : null;\r\n}\r\n\r\nfunction parseSortInput(value: unknown): WorkCenterSortRule[] {\r\n const parsed = parseJson(value);\r\n return Array.isArray(parsed)\r\n ? sanitizeSort(parsed as WorkCenterSortRule[])\r\n : [];\r\n}\r\n\r\nfunction parseFiltersInput(value: unknown): WorkCenterFilterRule[] {\r\n const parsed = parseJson(value);\r\n return Array.isArray(parsed)\r\n ? sanitizeFilters(parsed as WorkCenterFilterRule[])\r\n : [];\r\n}\r\n\r\nfunction hasParamValue(value: unknown): boolean {\r\n return value !== null && value !== undefined && value !== '';\r\n}\r\n\r\nfunction toLabel(value: string): string {\r\n const segment = value.split('.').pop() ?? value;\r\n return segment\r\n .replace(/[_-]/g, ' ')\r\n .replace(/([a-z])([A-Z])/g, '$1 $2')\r\n .replace(/\\s+/g, ' ')\r\n .trim()\r\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\r\n}\r\n\r\nfunction toColumnType(key: string): ColumnDef['type'] {\r\n return key.toLowerCase().includes('date') ? 'date' : 'text';\r\n}\r\n\r\nfunction mapViewTypeToColumnType(\r\n viewType: string | undefined,\r\n key: string,\r\n): ColumnDef['type'] {\r\n const normalized = viewType?.toLowerCase();\r\n if (normalized === 'date' || key.toLowerCase().includes('date')) {\r\n return 'date';\r\n }\r\n return 'text';\r\n}\r\n\r\nfunction buildColumnsFromProperties(\r\n properties: WorkCenterRuntimeProperty[],\r\n): ColumnDef[] {\r\n return properties\r\n .filter(\r\n (property) =>\r\n typeof property?.key === 'string' && property.key.length > 0,\r\n )\r\n .map((property) => ({\r\n key: property.key,\r\n label:\r\n property.name?.display ||\r\n property.name?.en ||\r\n property.name?.ar ||\r\n toLabel(property.key),\r\n type: mapViewTypeToColumnType(property.viewType, property.key),\r\n }));\r\n}\r\n\r\nfunction buildColumns(\r\n columnsConfig: WorkCenterColumnsConfig | null | undefined,\r\n): ColumnDef[] {\r\n const propertyColumns = buildColumnsFromProperties(\r\n columnsConfig?.properties ?? [],\r\n );\r\n if (propertyColumns.length) {\r\n return propertyColumns;\r\n }\r\n\r\n const keys = columnsConfig?.columns?.length ? columnsConfig.columns : [];\r\n return keys.map((key) => ({\r\n key,\r\n label: toLabel(key),\r\n type: toColumnType(key),\r\n }));\r\n}\r\n\r\nfunction buildMenuItems(cards: WorkCenterRuntimeCard[]): ClientPageMenuItem[] {\r\n const mapped = cards.map((card, index) => ({\r\n key: card.key,\r\n title:\r\n card.name?.display || card.name?.en || card.name?.ar || toLabel(card.key),\r\n subtitle: undefined,\r\n count: card.count ?? 0,\r\n color: AREA_COLORS[index % AREA_COLORS.length],\r\n icon: card.icon ?? 'custom.task',\r\n isAvailable: card.isAvailable !== false,\r\n }));\r\n\r\n const available = mapped.filter((card) => card.isAvailable);\r\n const source = available.length ? available : mapped;\r\n\r\n return source.map((card) => ({\r\n key: card.key,\r\n title: card.title,\r\n subtitle: undefined,\r\n count: card.count ?? 0,\r\n color: card.color,\r\n icon: card.icon ?? 'custom.task',\r\n }));\r\n}\r\n\r\nfunction buildKpis(\r\n stats: WorkCenterRuntimeStatsItem[],\r\n fallbackIcon: string | null,\r\n): StatisticCardData[] {\r\n return stats.map((stat, index) => ({\r\n title: String(stat.count ?? 0),\r\n subTitle: stat.label.display,\r\n icon: (fallbackIcon ?? 'custom.task') as any,\r\n color: KPI_COLORS[index % KPI_COLORS.length],\r\n }));\r\n}\r\n\r\nfunction createDefaultContext(area: WorkCenterArea): WorkCenterContext {\r\n return {\r\n area,\r\n templateId: null,\r\n selectedCardKey: null,\r\n page: 1,\r\n pageSize: 20,\r\n sort: [],\r\n runtimeFilters: [],\r\n includeStats: true,\r\n };\r\n}\r\n\r\nfunction createDefaultAreaState(area: WorkCenterArea): WorkCenterAreaState {\r\n return {\r\n context: createDefaultContext(area),\r\n menuItems: [],\r\n rows: [],\r\n columns: [],\r\n kpis: [],\r\n runtimeFilterSchema: null,\r\n totalCount: 0,\r\n warnings: [],\r\n lastLoadedAt: null,\r\n };\r\n}\r\n\r\nexport const WORK_CENTER_DEFAULT_STATE: WorkCenterStateModel = {\r\n activeArea: 'MyInbox',\r\n byArea: {\r\n MyInbox: createDefaultAreaState('MyInbox'),\r\n TasksCenter: createDefaultAreaState('TasksCenter'),\r\n },\r\n loadingActive: [],\r\n errors: {},\r\n};\r\n\r\nexport function normalizeContext(\r\n context: WorkCenterContext,\r\n): WorkCenterContext {\r\n return {\r\n ...context,\r\n page: clampPage(context.page, 1),\r\n pageSize: clampPageSize(context.pageSize, 20),\r\n sort: sanitizeSort(context.sort),\r\n runtimeFilters: sanitizeFilters(context.runtimeFilters),\r\n };\r\n}\r\n\r\nexport function buildContextFromInputs(\r\n currentContext: WorkCenterContext,\r\n area: WorkCenterArea,\r\n inputs: WorkCenterBootstrapInputs = {},\r\n): WorkCenterContext {\r\n const parsedCardKey = toSelectedCardKey(inputs.card);\r\n const parsedTemplateId = toOptionalInt(inputs.templateId);\r\n const parsedPage = toOptionalInt(inputs.page);\r\n const parsedPageSize = toOptionalInt(inputs.pageSize);\r\n\r\n return normalizeContext({\r\n ...currentContext,\r\n area,\r\n selectedCardKey: parsedCardKey ?? currentContext.selectedCardKey,\r\n page: parsedPage ?? currentContext.page,\r\n pageSize: parsedPageSize ?? currentContext.pageSize,\r\n templateId: parsedTemplateId ?? currentContext.templateId,\r\n sort: hasParamValue(inputs.sort)\r\n ? parseSortInput(inputs.sort)\r\n : currentContext.sort,\r\n runtimeFilters: hasParamValue(inputs.filters)\r\n ? parseFiltersInput(inputs.filters)\r\n : currentContext.runtimeFilters,\r\n });\r\n}\r\n\r\nexport function isSameContext(\r\n left: WorkCenterContext,\r\n right: WorkCenterContext,\r\n): boolean {\r\n return (\r\n left.area === right.area &&\r\n left.templateId === right.templateId &&\r\n left.selectedCardKey === right.selectedCardKey &&\r\n left.page === right.page &&\r\n left.pageSize === right.pageSize &&\r\n left.includeStats === right.includeStats &&\r\n JSON.stringify(left.sort) === JSON.stringify(right.sort) &&\r\n JSON.stringify(left.runtimeFilters) === JSON.stringify(right.runtimeFilters)\r\n );\r\n}\r\n\r\nexport function mapRuntimeResponse(\r\n current: WorkCenterAreaState,\r\n response: WorkCenterRuntimeResponseData,\r\n): WorkCenterAreaState {\r\n const selectedCard = response.selectedCard;\r\n const rows = selectedCard?.items ?? [];\r\n const menuItems = buildMenuItems(response.cards);\r\n const requestedCardKey =\r\n selectedCard?.key ?? current.context.selectedCardKey ?? null;\r\n const selectedCardKey =\r\n requestedCardKey &&\r\n response.cards.some((card) => card.key === requestedCardKey)\r\n ? requestedCardKey\r\n : (menuItems[0]?.key ?? response.cards[0]?.key ?? null);\r\n const selectedCardFromList = selectedCardKey\r\n ? (response.cards.find((card) => card.key === selectedCardKey) ?? null)\r\n : null;\r\n const selectedMenuItem = menuItems.find(\r\n (item) => item.key === selectedCardKey,\r\n );\r\n const columns = buildColumns(\r\n selectedCard?.columnsConfig ?? selectedCardFromList?.columnsConfig,\r\n );\r\n const kpis = buildKpis(\r\n selectedCard?.stats ?? [],\r\n selectedMenuItem?.icon ?? null,\r\n );\r\n\r\n return {\r\n ...current,\r\n menuItems,\r\n rows,\r\n columns,\r\n kpis,\r\n runtimeFilterSchema:\r\n selectedCard?.runtimeFilterSchema ??\r\n selectedCardFromList?.runtimeFilterSchema ??\r\n null,\r\n totalCount: selectedCard?.pagination.totalCount ?? 0,\r\n warnings: response.warnings ?? [],\r\n lastLoadedAt: new Date().toISOString(),\r\n context: {\r\n ...current.context,\r\n selectedCardKey,\r\n page: selectedCard?.pagination.page ?? current.context.page,\r\n pageSize: selectedCard?.pagination.pageSize ?? current.context.pageSize,\r\n },\r\n };\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { Injectable, inject } from '@angular/core';\r\nimport { Action, Selector, State, StateContext } from '@ngxs/store';\r\nimport { handleApiRequest } from '@masterteam/components';\r\nimport { EMPTY, catchError, map } from 'rxjs';\r\n\r\nimport {\r\n EnterArea,\r\n HydrateFromContext,\r\n LoadRuntime,\r\n SetParams,\r\n} from './work-center.actions';\r\nimport {\r\n ApiEnvelope,\r\n WorkCenterActionKey,\r\n WorkCenterArea,\r\n WorkCenterAreaState,\r\n WorkCenterRuntimeFilterSchema,\r\n WorkCenterRuntimeRequest,\r\n WorkCenterRuntimeResponseData,\r\n WorkCenterStateModel,\r\n} from './work-center.model';\r\nimport {\r\n buildContextFromInputs,\r\n isSameContext,\r\n mapRuntimeResponse,\r\n normalizeContext,\r\n WORK_CENTER_DEFAULT_STATE,\r\n} from './work-center.state.helpers';\r\n\r\n@State<WorkCenterStateModel>({\r\n name: 'workCenter',\r\n defaults: WORK_CENTER_DEFAULT_STATE,\r\n})\r\n@Injectable()\r\nexport class WorkCenterState {\r\n private readonly http = inject(HttpClient);\r\n\r\n @Selector()\r\n static getState(state: WorkCenterStateModel): WorkCenterStateModel {\r\n return state;\r\n }\r\n\r\n @Selector()\r\n static activeArea(state: WorkCenterStateModel): WorkCenterArea {\r\n return state.activeArea;\r\n }\r\n\r\n @Selector([WorkCenterState.activeArea, WorkCenterState.getState])\r\n static activeSnapshot(\r\n activeArea: WorkCenterArea,\r\n state: WorkCenterStateModel,\r\n ): WorkCenterAreaState {\r\n return state.byArea[activeArea];\r\n }\r\n\r\n @Selector([WorkCenterState.activeSnapshot])\r\n static context(snapshot: WorkCenterAreaState) {\r\n return snapshot.context;\r\n }\r\n\r\n @Selector([WorkCenterState.activeSnapshot])\r\n static menuItems(snapshot: WorkCenterAreaState) {\r\n return snapshot.menuItems;\r\n }\r\n\r\n @Selector([WorkCenterState.activeSnapshot])\r\n static rows(snapshot: WorkCenterAreaState) {\r\n return snapshot.rows;\r\n }\r\n\r\n @Selector([WorkCenterState.activeSnapshot])\r\n static columns(snapshot: WorkCenterAreaState) {\r\n return snapshot.columns;\r\n }\r\n\r\n @Selector([WorkCenterState.activeSnapshot])\r\n static kpis(snapshot: WorkCenterAreaState) {\r\n return snapshot.kpis;\r\n }\r\n\r\n @Selector([WorkCenterState.activeSnapshot])\r\n static runtimeFilterSchema(\r\n snapshot: WorkCenterAreaState,\r\n ): WorkCenterRuntimeFilterSchema | null {\r\n return snapshot.runtimeFilterSchema;\r\n }\r\n\r\n @Selector([WorkCenterState.activeSnapshot])\r\n static totalCount(snapshot: WorkCenterAreaState): number {\r\n return snapshot.totalCount;\r\n }\r\n\r\n @Selector([WorkCenterState.activeSnapshot])\r\n static warnings(snapshot: WorkCenterAreaState) {\r\n return snapshot.warnings;\r\n }\r\n\r\n @Selector()\r\n static getLoadingActive(state: WorkCenterStateModel): string[] {\r\n return state.loadingActive;\r\n }\r\n\r\n @Selector()\r\n static getErrors(state: WorkCenterStateModel): Record<string, string | null> {\r\n return state.errors;\r\n }\r\n\r\n @Action(EnterArea)\r\n enterArea(ctx: StateContext<WorkCenterStateModel>, action: EnterArea): void {\r\n if (ctx.getState().activeArea === action.area) return;\r\n ctx.patchState({ activeArea: action.area });\r\n }\r\n\r\n @Action(HydrateFromContext)\r\n hydrateFromContext(\r\n ctx: StateContext<WorkCenterStateModel>,\r\n action: HydrateFromContext,\r\n ): void {\r\n const state = ctx.getState();\r\n const current = state.byArea[action.area];\r\n const nextContext = normalizeContext({\r\n ...current.context,\r\n ...action.patch,\r\n area: action.area,\r\n });\r\n\r\n if (\r\n state.activeArea === action.area &&\r\n isSameContext(current.context, nextContext)\r\n ) {\r\n return;\r\n }\r\n\r\n ctx.patchState({\r\n activeArea: action.area,\r\n byArea: {\r\n ...state.byArea,\r\n [action.area]: { ...current, context: nextContext },\r\n },\r\n });\r\n }\r\n\r\n @Action(SetParams)\r\n setParams(ctx: StateContext<WorkCenterStateModel>, action: SetParams) {\r\n const state = ctx.getState();\r\n const current = state.byArea[action.area];\r\n const nextContext = buildContextFromInputs(\r\n current.context,\r\n action.area,\r\n action.inputs,\r\n );\r\n\r\n const areaChanged = state.activeArea !== action.area;\r\n const contextChanged = !isSameContext(current.context, nextContext);\r\n const runtimeLoading = state.loadingActive.includes(\r\n WorkCenterActionKey.LoadRuntime,\r\n );\r\n const shouldLoad =\r\n areaChanged ||\r\n contextChanged ||\r\n (!current.lastLoadedAt && !runtimeLoading);\r\n\r\n if (areaChanged || contextChanged) {\r\n ctx.patchState({\r\n activeArea: action.area,\r\n byArea: {\r\n ...state.byArea,\r\n [action.area]: { ...current, context: nextContext },\r\n },\r\n });\r\n }\r\n\r\n if (!shouldLoad) return;\r\n return ctx.dispatch(new LoadRuntime(action.area, 'route-enter'));\r\n }\r\n\r\n @Action(LoadRuntime)\r\n loadRuntime(ctx: StateContext<WorkCenterStateModel>, action: LoadRuntime) {\r\n const state = ctx.getState();\r\n const areaState = state.byArea[action.area];\r\n const request = normalizeContext(areaState.context);\r\n const nextAreaState = {\r\n ...areaState,\r\n rows: [],\r\n columns: [],\r\n kpis: [],\r\n totalCount: 0,\r\n };\r\n\r\n ctx.patchState({\r\n byArea: {\r\n ...state.byArea,\r\n [action.area]: nextAreaState,\r\n },\r\n });\r\n\r\n return handleApiRequest({\r\n ctx,\r\n key: WorkCenterActionKey.LoadRuntime,\r\n request$: this.getRuntime(request),\r\n onSuccess: (response, latestState) => {\r\n const current = latestState.byArea[action.area];\r\n return {\r\n byArea: {\r\n ...latestState.byArea,\r\n [action.area]: mapRuntimeResponse(current, response),\r\n },\r\n };\r\n },\r\n errorMessage: 'Failed to load Work Center runtime.',\r\n }).pipe(catchError(() => EMPTY));\r\n }\r\n\r\n private getRuntime(request: WorkCenterRuntimeRequest) {\r\n return this.http\r\n .post<\r\n ApiEnvelope<WorkCenterRuntimeResponseData>\r\n >('workcenter/runtime', request)\r\n .pipe(\r\n map((response) => {\r\n if (response.code === 1) return response.data;\r\n\r\n const fallbackError = 'Failed to load Work Center runtime.';\r\n const message =\r\n (response.errors as { message?: string } | null)?.message ??\r\n response.message ??\r\n fallbackError;\r\n\r\n throw new Error(message);\r\n }),\r\n );\r\n }\r\n}\r\n","import { Injectable, computed, inject } from '@angular/core';\r\nimport { select, Store } from '@ngxs/store';\r\n\r\nimport {\r\n EnterArea,\r\n HydrateFromContext,\r\n LoadRuntime,\r\n SetParams,\r\n} from './work-center.actions';\r\nimport {\r\n WorkCenterActionKey,\r\n WorkCenterArea,\r\n WorkCenterBootstrapInputs,\r\n WorkCenterFilterRule,\r\n WorkCenterHydratePatch,\r\n WorkCenterLoadReason,\r\n WorkCenterSortRule,\r\n WORK_CENTER_MAX_PAGE_SIZE,\r\n} from './work-center.model';\r\nimport { WorkCenterState } from './work-center.state';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class WorkCenterFacade {\r\n private readonly store = inject(Store);\r\n\r\n readonly activeArea = select(WorkCenterState.activeArea);\r\n readonly context = select(WorkCenterState.context);\r\n readonly menuItems = select(WorkCenterState.menuItems);\r\n readonly rows = select(WorkCenterState.rows);\r\n readonly columns = select(WorkCenterState.columns);\r\n readonly kpis = select(WorkCenterState.kpis);\r\n readonly runtimeFilterSchema = select(WorkCenterState.runtimeFilterSchema);\r\n readonly totalCount = select(WorkCenterState.totalCount);\r\n readonly warnings = select(WorkCenterState.warnings);\r\n\r\n private readonly loadingActive = select(WorkCenterState.getLoadingActive);\r\n private readonly errors = select(WorkCenterState.getErrors);\r\n\r\n readonly loading = computed(() =>\r\n this.loadingActive().includes(WorkCenterActionKey.LoadRuntime),\r\n );\r\n readonly error = computed(\r\n () => this.errors()[WorkCenterActionKey.LoadRuntime] ?? null,\r\n );\r\n\r\n enterArea(area: WorkCenterArea) {\r\n return this.store.dispatch(new EnterArea(area));\r\n }\r\n\r\n hydrateContext(area: WorkCenterArea, patch: WorkCenterHydratePatch) {\r\n return this.store.dispatch(new HydrateFromContext(area, patch));\r\n }\r\n\r\n setParams(area: WorkCenterArea, inputs: WorkCenterBootstrapInputs) {\r\n return this.store.dispatch(new SetParams(area, inputs));\r\n }\r\n\r\n selectCardAndLoad(area: WorkCenterArea, selectedCardKey: string) {\r\n return this.store.dispatch([\r\n new HydrateFromContext(area, { selectedCardKey, page: 1 }),\r\n new LoadRuntime(area, 'menu-change'),\r\n ]);\r\n }\r\n\r\n applyTableLazyLoadAndLoad(area: WorkCenterArea, event: any) {\r\n const context = this.store.selectSnapshot(WorkCenterState.context);\r\n const patch: WorkCenterHydratePatch = {};\r\n let changed = false;\r\n\r\n const page = this.toPositiveInt(event?.currentPage);\r\n if (page !== null && page !== context.page) {\r\n patch.page = page;\r\n changed = true;\r\n }\r\n\r\n const pageSize = this.toPositiveInt(event?.pageSize);\r\n if (pageSize !== null) {\r\n const normalizedPageSize = Math.min(\r\n WORK_CENTER_MAX_PAGE_SIZE,\r\n Math.max(1, pageSize),\r\n );\r\n if (normalizedPageSize !== context.pageSize) {\r\n patch.pageSize = normalizedPageSize;\r\n changed = true;\r\n }\r\n }\r\n\r\n const sort = this.toSortFromLazyEvent(event);\r\n if (sort && !this.isSameSort(sort, context.sort)) {\r\n patch.sort = sort;\r\n changed = true;\r\n }\r\n\r\n if (!changed) {\r\n return;\r\n }\r\n\r\n return this.store.dispatch([\r\n new HydrateFromContext(area, patch),\r\n new LoadRuntime(area, 'table-lazy'),\r\n ]);\r\n }\r\n\r\n applyRuntimeFiltersAndLoad(\r\n area: WorkCenterArea,\r\n runtimeFilters: WorkCenterFilterRule[],\r\n ) {\r\n return this.store.dispatch([\r\n new HydrateFromContext(area, { runtimeFilters, page: 1 }),\r\n new LoadRuntime(area, 'filters-change'),\r\n ]);\r\n }\r\n\r\n loadRuntime(area: WorkCenterArea, reason: WorkCenterLoadReason = 'manual') {\r\n return this.store.dispatch(new LoadRuntime(area, reason));\r\n }\r\n\r\n private toPositiveInt(value: unknown): number | null {\r\n const parsed = Number(value);\r\n if (!Number.isFinite(parsed)) {\r\n return null;\r\n }\r\n return Math.max(1, Math.floor(parsed));\r\n }\r\n\r\n private toSortFromLazyEvent(event: any): WorkCenterSortRule[] | null {\r\n const sortField = event?.sortField;\r\n if (typeof sortField !== 'string' || !sortField.length) {\r\n return null;\r\n }\r\n\r\n return [\r\n {\r\n field: sortField,\r\n dir: event?.sortOrder === -1 ? 'desc' : 'asc',\r\n },\r\n ];\r\n }\r\n\r\n private isSameSort(\r\n left: WorkCenterSortRule[] | undefined,\r\n right: WorkCenterSortRule[] | undefined,\r\n ): boolean {\r\n const leftValue = left ?? [];\r\n const rightValue = right ?? [];\r\n\r\n if (leftValue.length !== rightValue.length) {\r\n return false;\r\n }\r\n\r\n return leftValue.every(\r\n (rule, index) =>\r\n rule.field === rightValue[index]?.field &&\r\n rule.dir === rightValue[index]?.dir,\r\n );\r\n }\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { Component, computed, inject, input, output } from '@angular/core';\r\nimport { ClientPage } from '@masterteam/components/client-page';\r\nimport { ClientPageMenuItem } from '@masterteam/components/client-page-menu';\r\nimport { Page } from '@masterteam/components/page';\r\nimport {\r\n PropertyFilterBuilder,\r\n PropertyFilterBuilderRule,\r\n PropertyFilterBuilderSchema,\r\n} from '@masterteam/components/property-filter-builder';\r\nimport { StatisticCard } from '@masterteam/components/statistic-card';\r\nimport { Table } from '@masterteam/components/table';\r\nimport { SkeletonModule } from 'primeng/skeleton';\r\n\r\nimport { WorkCenterFacade } from '../../store/work-center/work-center.facade';\r\nimport {\r\n WorkCenterArea,\r\n WorkCenterFilterRule,\r\n WorkCenterRuntimeFilterSchema,\r\n} from '../../store/work-center/work-center.model';\r\n\r\nconst OPERATOR_LABELS: Record<string, string> = {\r\n Eq: 'Equals',\r\n Neq: 'Not equal',\r\n In: 'In',\r\n Contains: 'Contains',\r\n StartsWith: 'Starts with',\r\n Gt: 'Greater than',\r\n Gte: 'Greater than or equal',\r\n Lt: 'Less than',\r\n Lte: 'Less than or equal',\r\n Between: 'Between',\r\n IsNull: 'Is empty',\r\n IsNotNull: 'Is not empty',\r\n};\r\n\r\nconst OPERATOR_VALUE_MODE: Record<\r\n string,\r\n 'single' | 'multi' | 'range' | 'none'\r\n> = {\r\n In: 'multi',\r\n Between: 'range',\r\n IsNull: 'none',\r\n IsNotNull: 'none',\r\n};\r\n\r\nfunction toLabel(value: string): string {\r\n const normalized = value.split('.').pop() ?? value;\r\n return normalized\r\n .replace(/[_-]/g, ' ')\r\n .replace(/([a-z])([A-Z])/g, '$1 $2')\r\n .trim()\r\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\r\n}\r\n\r\nfunction columnTypeToViewType(type: string | undefined): string | undefined {\r\n if (type === 'date') return 'Date';\r\n return undefined;\r\n}\r\n\r\nfunction mapAllowedFields(schema: WorkCenterRuntimeFilterSchema) {\r\n const properties = schema.properties ?? [];\r\n const fromProperties = properties\r\n .filter(\r\n (property) =>\r\n typeof property?.key === 'string' && property.key.length > 0,\r\n )\r\n .map((property) => ({\r\n key: property.key,\r\n label:\r\n property.name?.display ||\r\n property.name?.en ||\r\n property.name?.ar ||\r\n toLabel(property.key),\r\n viewType: property.viewType,\r\n }));\r\n\r\n if (fromProperties.length) {\r\n return fromProperties;\r\n }\r\n\r\n return (schema.allowedFields ?? []).map((field) => ({\r\n key: field,\r\n label: toLabel(field),\r\n }));\r\n}\r\n\r\nfunction mapAllowedOperators(schema: WorkCenterRuntimeFilterSchema) {\r\n const options: Array<{\r\n key: string;\r\n label: string;\r\n valueMode: 'single' | 'multi' | 'range' | 'none';\r\n }> = [];\r\n\r\n for (const operator of schema.allowedOperators ?? []) {\r\n if (typeof operator === 'string') {\r\n options.push({\r\n key: operator,\r\n label: OPERATOR_LABELS[operator] ?? toLabel(operator),\r\n valueMode: OPERATOR_VALUE_MODE[operator] ?? 'single',\r\n });\r\n continue;\r\n }\r\n\r\n const key = operator?.value;\r\n if (!key) {\r\n continue;\r\n }\r\n\r\n options.push({\r\n key,\r\n label:\r\n operator.display?.display ||\r\n operator.display?.en ||\r\n operator.display?.ar ||\r\n OPERATOR_LABELS[key] ||\r\n toLabel(key),\r\n valueMode: OPERATOR_VALUE_MODE[key] ?? 'single',\r\n });\r\n }\r\n\r\n return options;\r\n}\r\n\r\n@Component({\r\n selector: 'mt-work-center-page',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n ClientPage,\r\n Page,\r\n PropertyFilterBuilder,\r\n StatisticCard,\r\n Table,\r\n SkeletonModule,\r\n ],\r\n templateUrl: './work-center-page.html',\r\n})\r\nexport class WorkCenterPage {\r\n private readonly facade = inject(WorkCenterFacade);\r\n\r\n readonly area = input<WorkCenterArea>('MyInbox');\r\n readonly pageTitle = input<string>('Work Center');\r\n readonly menuIcon = input<string>('communication.inbox-01');\r\n\r\n readonly runtimeFiltersChanged = output<WorkCenterFilterRule[]>();\r\n\r\n protected readonly context = this.facade.context;\r\n protected readonly menuItems = this.facade.menuItems;\r\n protected readonly rows = this.facade.rows;\r\n protected readonly columns = this.facade.columns;\r\n protected readonly kpis = this.facade.kpis;\r\n protected readonly runtimeFilterSchema = this.facade.runtimeFilterSchema;\r\n protected readonly totalCount = this.facade.totalCount;\r\n protected readonly loading = this.facade.loading;\r\n\r\n protected readonly tableCurrentPage = computed(() =>\r\n Math.max((this.context().page ?? 1) - 1, 0),\r\n );\r\n protected readonly tableFirst = computed(\r\n () => this.tableCurrentPage() * (this.context().pageSize || 20),\r\n );\r\n\r\n protected readonly propertyFilterSchema =\r\n computed<PropertyFilterBuilderSchema | null>(() => {\r\n const schema = this.runtimeFilterSchema();\r\n if (schema) {\r\n const allowedFields = mapAllowedFields(schema);\r\n const allowedOperators = mapAllowedOperators(schema);\r\n if (allowedFields.length && allowedOperators.length) {\r\n return { allowedFields, allowedOperators };\r\n }\r\n }\r\n\r\n const fallbackFields = this.columns()\r\n .filter(\r\n (column) => typeof column?.key === 'string' && column.key.length > 0,\r\n )\r\n .map((column) => ({\r\n key: column.key,\r\n label: column.label || toLabel(column.key),\r\n viewType: columnTypeToViewType(column.type),\r\n }));\r\n\r\n if (!fallbackFields.length) {\r\n return null;\r\n }\r\n\r\n const fallbackOperators = Object.keys(OPERATOR_LABELS).map((key) => ({\r\n key,\r\n label: OPERATOR_LABELS[key] ?? toLabel(key),\r\n valueMode: OPERATOR_VALUE_MODE[key] ?? 'single',\r\n }));\r\n\r\n return {\r\n allowedFields: fallbackFields,\r\n allowedOperators: fallbackOperators,\r\n };\r\n });\r\n\r\n onMenuItemClick(item: ClientPageMenuItem): void {\r\n this.facade.selectCardAndLoad(this.area(), item.key);\r\n }\r\n\r\n onLazyLoad(event: any): void {\r\n this.facade.applyTableLazyLoadAndLoad(this.area(), event);\r\n }\r\n\r\n onRuntimeFiltersApplied(filters: PropertyFilterBuilderRule[]): void {\r\n this.runtimeFiltersChanged.emit(\r\n filters.map((filter) => ({\r\n field: filter.field,\r\n op: filter.op as WorkCenterFilterRule['op'],\r\n value: filter.value,\r\n values: filter.values,\r\n from: filter.from,\r\n to: filter.to,\r\n })),\r\n );\r\n }\r\n\r\n onRuntimeFiltersCleared(): void {\r\n this.runtimeFiltersChanged.emit([]);\r\n }\r\n}\r\n","<mt-page [title]=\"pageTitle()\" [avatarIcon]=\"menuIcon()\">\r\n <div class=\"h-full min-h-0\">\r\n <mt-client-page\r\n [menuIcon]=\"menuIcon()\"\r\n [menuTitle]=\"pageTitle()\"\r\n [menuItems]=\"menuItems()\"\r\n [menuItemsLoading]=\"loading() && !menuItems().length\"\r\n [activeItem]=\"context().selectedCardKey ?? undefined\"\r\n (menuItemClick)=\"onMenuItemClick($event)\"\r\n >\r\n <ng-template #headerClientPageEnd>\r\n <mt-property-filter-builder\r\n [schema]=\"propertyFilterSchema()\"\r\n [filters]=\"context().runtimeFilters\"\r\n (applied)=\"onRuntimeFiltersApplied($event)\"\r\n (cleared)=\"onRuntimeFiltersCleared()\"\r\n />\r\n </ng-template>\r\n\r\n <div class=\"flex flex-col gap-4\">\r\n @if (loading()) {\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n @for (_ of [1, 2, 3, 4]; track $index) {\r\n <p-skeleton height=\"6.5rem\" borderRadius=\"1rem\" />\r\n }\r\n </div>\r\n } @else if (kpis().length) {\r\n <div class=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-3\">\r\n @for (kpi of kpis(); track $index) {\r\n <mt-statistic-card [data]=\"kpi\" />\r\n }\r\n </div>\r\n }\r\n\r\n <mt-table\r\n [data]=\"rows()\"\r\n [columns]=\"columns()\"\r\n [lazy]=\"true\"\r\n [loading]=\"loading()\"\r\n [lazyTotalRecords]=\"totalCount()\"\r\n [showFilters]=\"false\"\r\n [generalSearch]=\"false\"\r\n [pageSize]=\"context().pageSize\"\r\n [currentPage]=\"tableCurrentPage()\"\r\n [first]=\"tableFirst()\"\r\n (lazyLoad)=\"onLazyLoad($event)\"\r\n />\r\n </div>\r\n </mt-client-page>\r\n </div>\r\n</mt-page>\r\n","import { WorkCenterState } from './work-center';\r\n\r\nexport const APP_STATES = [WorkCenterState];\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["toLabel"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@masterteam/work-center",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"directory": "../../../dist/masterteam/work-center",
|
|
6
|
+
"linkDirectory": false,
|
|
7
|
+
"access": "public"
|
|
8
|
+
},
|
|
9
|
+
"peerDependencies": {
|
|
10
|
+
"@angular/common": "^21.0.3",
|
|
11
|
+
"@angular/core": "^21.0.3",
|
|
12
|
+
"@angular/forms": "^21.0.3",
|
|
13
|
+
"@angular/router": "^21.0.3",
|
|
14
|
+
"@jsverse/transloco": "^8.0.2",
|
|
15
|
+
"@ngxs/store": "^20.1.0",
|
|
16
|
+
"@primeuix/themes": "^2.0.2",
|
|
17
|
+
"@tailwindcss/postcss": "^4.1.17",
|
|
18
|
+
"postcss": "^8.5.6",
|
|
19
|
+
"primeng": "21.0.1",
|
|
20
|
+
"rxjs": "^7.8.2",
|
|
21
|
+
"tailwindcss": "^4.1.17",
|
|
22
|
+
"tailwindcss-primeui": "^0.6.1",
|
|
23
|
+
"@masterteam/components": "^0.0.90",
|
|
24
|
+
"@masterteam/icons": "^0.0.13"
|
|
25
|
+
},
|
|
26
|
+
"sideEffects": false,
|
|
27
|
+
"exports": {
|
|
28
|
+
"./assets/work-center.css": {
|
|
29
|
+
"style": "./assets/work-center.css"
|
|
30
|
+
},
|
|
31
|
+
"./package.json": {
|
|
32
|
+
"default": "./package.json"
|
|
33
|
+
},
|
|
34
|
+
".": {
|
|
35
|
+
"types": "./types/masterteam-work-center.d.ts",
|
|
36
|
+
"default": "./fesm2022/masterteam-work-center.mjs"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"module": "fesm2022/masterteam-work-center.mjs",
|
|
40
|
+
"typings": "types/masterteam-work-center.d.ts",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"tslib": "^2.8.1"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import * as _masterteam_components_statistic_card from '@masterteam/components/statistic-card';
|
|
2
|
+
import { StatisticCardData } from '@masterteam/components/statistic-card';
|
|
3
|
+
import * as _masterteam_components_table from '@masterteam/components/table';
|
|
4
|
+
import { ColumnDef } from '@masterteam/components/table';
|
|
5
|
+
import * as _masterteam_work_center from '@masterteam/work-center';
|
|
6
|
+
import * as _angular_core from '@angular/core';
|
|
7
|
+
import { ClientPageMenuItem } from '@masterteam/components/client-page-menu';
|
|
8
|
+
import { PropertyFilterBuilderSchema, PropertyFilterBuilderRule } from '@masterteam/components/property-filter-builder';
|
|
9
|
+
import { LoadingStateShape } from '@masterteam/components';
|
|
10
|
+
import * as rxjs from 'rxjs';
|
|
11
|
+
import * as _masterteam_components_types_masterteam_components_statistic_card from '@masterteam/components/types/masterteam-components-statistic-card';
|
|
12
|
+
import * as _masterteam_components_types_masterteam_components_table from '@masterteam/components/types/masterteam-components-table';
|
|
13
|
+
import * as _masterteam_components_types_masterteam_components_client_page_menu from '@masterteam/components/types/masterteam-components-client-page-menu';
|
|
14
|
+
import { StateContext } from '@ngxs/store';
|
|
15
|
+
|
|
16
|
+
type WorkCenterArea = 'MyInbox' | 'TasksCenter';
|
|
17
|
+
declare enum WorkCenterActionKey {
|
|
18
|
+
LoadRuntime = "loadRuntime"
|
|
19
|
+
}
|
|
20
|
+
declare const WORK_CENTER_QUERY_VERSION = 1;
|
|
21
|
+
declare const WORK_CENTER_MAX_PAGE_SIZE = 100;
|
|
22
|
+
declare const WORK_CENTER_MAX_FILTERS = 20;
|
|
23
|
+
declare const WORK_CENTER_MAX_SORT = 5;
|
|
24
|
+
interface ApiEnvelope<T> {
|
|
25
|
+
endpoint: string | null;
|
|
26
|
+
status: number;
|
|
27
|
+
code: 1 | 2;
|
|
28
|
+
locale: string | null;
|
|
29
|
+
message: string | null;
|
|
30
|
+
errors: unknown;
|
|
31
|
+
data: T;
|
|
32
|
+
cacheSession: string | null;
|
|
33
|
+
}
|
|
34
|
+
interface TranslatableDto {
|
|
35
|
+
display: string;
|
|
36
|
+
en: string;
|
|
37
|
+
ar: string;
|
|
38
|
+
}
|
|
39
|
+
interface WorkCenterSortRule {
|
|
40
|
+
field: string;
|
|
41
|
+
dir: 'asc' | 'desc';
|
|
42
|
+
}
|
|
43
|
+
type WorkCenterFilterOperator = 'Eq' | 'Neq' | 'In' | 'Contains' | 'StartsWith' | 'Gt' | 'Gte' | 'Lt' | 'Lte' | 'Between' | 'IsNull' | 'IsNotNull';
|
|
44
|
+
interface WorkCenterFilterRule {
|
|
45
|
+
field: string;
|
|
46
|
+
op: WorkCenterFilterOperator;
|
|
47
|
+
value?: unknown;
|
|
48
|
+
values?: unknown[];
|
|
49
|
+
from?: unknown;
|
|
50
|
+
to?: unknown;
|
|
51
|
+
}
|
|
52
|
+
interface WorkCenterRuntimeProperty {
|
|
53
|
+
id?: number;
|
|
54
|
+
key: string;
|
|
55
|
+
normalizedKey?: string;
|
|
56
|
+
name?: TranslatableDto;
|
|
57
|
+
description?: TranslatableDto;
|
|
58
|
+
viewType?: string;
|
|
59
|
+
}
|
|
60
|
+
interface WorkCenterRuntimeOperatorOption {
|
|
61
|
+
value: WorkCenterFilterOperator;
|
|
62
|
+
display?: TranslatableDto;
|
|
63
|
+
}
|
|
64
|
+
interface WorkCenterRuntimeFilterSchema {
|
|
65
|
+
properties?: WorkCenterRuntimeProperty[];
|
|
66
|
+
allowedFields?: string[];
|
|
67
|
+
allowedOperators: Array<WorkCenterFilterOperator | WorkCenterRuntimeOperatorOption>;
|
|
68
|
+
}
|
|
69
|
+
interface WorkCenterColumnsConfig {
|
|
70
|
+
columns?: string[];
|
|
71
|
+
properties?: WorkCenterRuntimeProperty[];
|
|
72
|
+
}
|
|
73
|
+
interface WorkCenterRuntimeRequest {
|
|
74
|
+
area: WorkCenterArea;
|
|
75
|
+
templateId?: number | null;
|
|
76
|
+
selectedCardKey?: string | null;
|
|
77
|
+
page: number;
|
|
78
|
+
pageSize: number;
|
|
79
|
+
sort: WorkCenterSortRule[];
|
|
80
|
+
runtimeFilters: WorkCenterFilterRule[];
|
|
81
|
+
includeStats: boolean;
|
|
82
|
+
}
|
|
83
|
+
interface WorkCenterRuntimeCard {
|
|
84
|
+
key: string;
|
|
85
|
+
name: TranslatableDto;
|
|
86
|
+
icon: string | null;
|
|
87
|
+
urlTemplate?: string | null;
|
|
88
|
+
runtimeFilterSchema?: WorkCenterRuntimeFilterSchema | null;
|
|
89
|
+
columnsConfig?: WorkCenterColumnsConfig | null;
|
|
90
|
+
count: number;
|
|
91
|
+
isAvailable: boolean;
|
|
92
|
+
}
|
|
93
|
+
interface WorkCenterRuntimeStatsItem {
|
|
94
|
+
key: string;
|
|
95
|
+
label: TranslatableDto;
|
|
96
|
+
count: number;
|
|
97
|
+
}
|
|
98
|
+
interface WorkCenterRuntimePagination {
|
|
99
|
+
page: number;
|
|
100
|
+
pageSize: number;
|
|
101
|
+
totalCount: number;
|
|
102
|
+
}
|
|
103
|
+
interface WorkCenterRuntimeSelectedCard {
|
|
104
|
+
key: string;
|
|
105
|
+
pagination: WorkCenterRuntimePagination;
|
|
106
|
+
stats: WorkCenterRuntimeStatsItem[];
|
|
107
|
+
items: Record<string, unknown>[];
|
|
108
|
+
runtimeFilterSchema?: WorkCenterRuntimeFilterSchema | null;
|
|
109
|
+
columnsConfig?: WorkCenterColumnsConfig | null;
|
|
110
|
+
}
|
|
111
|
+
interface WorkCenterRuntimeWarningDto {
|
|
112
|
+
code: string;
|
|
113
|
+
message: string;
|
|
114
|
+
cardKey: string | null;
|
|
115
|
+
source: string | null;
|
|
116
|
+
}
|
|
117
|
+
interface WorkCenterRuntimeResponseData {
|
|
118
|
+
area: WorkCenterArea;
|
|
119
|
+
cards: WorkCenterRuntimeCard[];
|
|
120
|
+
selectedCard: WorkCenterRuntimeSelectedCard | null;
|
|
121
|
+
warnings: WorkCenterRuntimeWarningDto[];
|
|
122
|
+
}
|
|
123
|
+
interface WorkCenterContext {
|
|
124
|
+
area: WorkCenterArea;
|
|
125
|
+
templateId: number | null;
|
|
126
|
+
selectedCardKey: string | null;
|
|
127
|
+
page: number;
|
|
128
|
+
pageSize: number;
|
|
129
|
+
sort: WorkCenterSortRule[];
|
|
130
|
+
runtimeFilters: WorkCenterFilterRule[];
|
|
131
|
+
includeStats: boolean;
|
|
132
|
+
}
|
|
133
|
+
interface WorkCenterAreaState {
|
|
134
|
+
context: WorkCenterContext;
|
|
135
|
+
menuItems: ClientPageMenuItem[];
|
|
136
|
+
rows: Record<string, unknown>[];
|
|
137
|
+
columns: ColumnDef[];
|
|
138
|
+
kpis: StatisticCardData[];
|
|
139
|
+
runtimeFilterSchema: WorkCenterRuntimeFilterSchema | null;
|
|
140
|
+
totalCount: number;
|
|
141
|
+
warnings: WorkCenterRuntimeWarningDto[];
|
|
142
|
+
lastLoadedAt: string | null;
|
|
143
|
+
}
|
|
144
|
+
interface WorkCenterStateModel extends LoadingStateShape<WorkCenterActionKey> {
|
|
145
|
+
activeArea: WorkCenterArea;
|
|
146
|
+
byArea: Record<WorkCenterArea, WorkCenterAreaState>;
|
|
147
|
+
}
|
|
148
|
+
interface WorkCenterHydratePatch {
|
|
149
|
+
selectedCardKey?: string | null;
|
|
150
|
+
page?: number;
|
|
151
|
+
pageSize?: number;
|
|
152
|
+
templateId?: number | null;
|
|
153
|
+
sort?: WorkCenterSortRule[];
|
|
154
|
+
runtimeFilters?: WorkCenterFilterRule[];
|
|
155
|
+
}
|
|
156
|
+
interface WorkCenterBootstrapInputs {
|
|
157
|
+
card?: unknown;
|
|
158
|
+
page?: unknown;
|
|
159
|
+
pageSize?: unknown;
|
|
160
|
+
templateId?: unknown;
|
|
161
|
+
sort?: unknown;
|
|
162
|
+
filters?: unknown;
|
|
163
|
+
}
|
|
164
|
+
type WorkCenterLoadReason = 'route-enter' | 'menu-change' | 'filters-change' | 'table-lazy' | 'refresh' | 'manual';
|
|
165
|
+
|
|
166
|
+
declare class WorkCenterPage {
|
|
167
|
+
private readonly facade;
|
|
168
|
+
readonly area: _angular_core.InputSignal<WorkCenterArea>;
|
|
169
|
+
readonly pageTitle: _angular_core.InputSignal<string>;
|
|
170
|
+
readonly menuIcon: _angular_core.InputSignal<string>;
|
|
171
|
+
readonly runtimeFiltersChanged: _angular_core.OutputEmitterRef<WorkCenterFilterRule[]>;
|
|
172
|
+
protected readonly context: _angular_core.Signal<_masterteam_work_center.WorkCenterContext>;
|
|
173
|
+
protected readonly menuItems: _angular_core.Signal<ClientPageMenuItem[]>;
|
|
174
|
+
protected readonly rows: _angular_core.Signal<Record<string, unknown>[]>;
|
|
175
|
+
protected readonly columns: _angular_core.Signal<_masterteam_components_table.ColumnDef[]>;
|
|
176
|
+
protected readonly kpis: _angular_core.Signal<_masterteam_components_statistic_card.StatisticCardData[]>;
|
|
177
|
+
protected readonly runtimeFilterSchema: _angular_core.Signal<WorkCenterRuntimeFilterSchema | null>;
|
|
178
|
+
protected readonly totalCount: _angular_core.Signal<number>;
|
|
179
|
+
protected readonly loading: _angular_core.Signal<boolean>;
|
|
180
|
+
protected readonly tableCurrentPage: _angular_core.Signal<number>;
|
|
181
|
+
protected readonly tableFirst: _angular_core.Signal<number>;
|
|
182
|
+
protected readonly propertyFilterSchema: _angular_core.Signal<PropertyFilterBuilderSchema | null>;
|
|
183
|
+
onMenuItemClick(item: ClientPageMenuItem): void;
|
|
184
|
+
onLazyLoad(event: any): void;
|
|
185
|
+
onRuntimeFiltersApplied(filters: PropertyFilterBuilderRule[]): void;
|
|
186
|
+
onRuntimeFiltersCleared(): void;
|
|
187
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WorkCenterPage, never>;
|
|
188
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<WorkCenterPage, "mt-work-center-page", never, { "area": { "alias": "area"; "required": false; "isSignal": true; }; "pageTitle": { "alias": "pageTitle"; "required": false; "isSignal": true; }; "menuIcon": { "alias": "menuIcon"; "required": false; "isSignal": true; }; }, { "runtimeFiltersChanged": "runtimeFiltersChanged"; }, never, never, true, never>;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
declare class EnterArea {
|
|
192
|
+
area: WorkCenterArea;
|
|
193
|
+
static readonly type = "[WorkCenter] Enter Area";
|
|
194
|
+
constructor(area: WorkCenterArea);
|
|
195
|
+
}
|
|
196
|
+
declare class HydrateFromContext {
|
|
197
|
+
area: WorkCenterArea;
|
|
198
|
+
patch: WorkCenterHydratePatch;
|
|
199
|
+
static readonly type = "[WorkCenter] Hydrate From Context";
|
|
200
|
+
constructor(area: WorkCenterArea, patch: WorkCenterHydratePatch);
|
|
201
|
+
}
|
|
202
|
+
declare class SetParams {
|
|
203
|
+
area: WorkCenterArea;
|
|
204
|
+
inputs: WorkCenterBootstrapInputs;
|
|
205
|
+
static readonly type = "[WorkCenter] Set Params";
|
|
206
|
+
constructor(area: WorkCenterArea, inputs: WorkCenterBootstrapInputs);
|
|
207
|
+
}
|
|
208
|
+
declare class LoadRuntime {
|
|
209
|
+
area: WorkCenterArea;
|
|
210
|
+
reason: WorkCenterLoadReason;
|
|
211
|
+
static readonly type = "[WorkCenter] Load Runtime";
|
|
212
|
+
constructor(area: WorkCenterArea, reason?: WorkCenterLoadReason);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
declare class WorkCenterFacade {
|
|
216
|
+
private readonly store;
|
|
217
|
+
readonly activeArea: _angular_core.Signal<WorkCenterArea>;
|
|
218
|
+
readonly context: _angular_core.Signal<_masterteam_work_center.WorkCenterContext>;
|
|
219
|
+
readonly menuItems: _angular_core.Signal<_masterteam_components_types_masterteam_components_client_page_menu.ClientPageMenuItem[]>;
|
|
220
|
+
readonly rows: _angular_core.Signal<Record<string, unknown>[]>;
|
|
221
|
+
readonly columns: _angular_core.Signal<_masterteam_components_types_masterteam_components_table.ColumnDef[]>;
|
|
222
|
+
readonly kpis: _angular_core.Signal<_masterteam_components_types_masterteam_components_statistic_card.StatisticCardData[]>;
|
|
223
|
+
readonly runtimeFilterSchema: _angular_core.Signal<_masterteam_work_center.WorkCenterRuntimeFilterSchema | null>;
|
|
224
|
+
readonly totalCount: _angular_core.Signal<number>;
|
|
225
|
+
readonly warnings: _angular_core.Signal<_masterteam_work_center.WorkCenterRuntimeWarningDto[]>;
|
|
226
|
+
private readonly loadingActive;
|
|
227
|
+
private readonly errors;
|
|
228
|
+
readonly loading: _angular_core.Signal<boolean>;
|
|
229
|
+
readonly error: _angular_core.Signal<string | null>;
|
|
230
|
+
enterArea(area: WorkCenterArea): rxjs.Observable<void>;
|
|
231
|
+
hydrateContext(area: WorkCenterArea, patch: WorkCenterHydratePatch): rxjs.Observable<void>;
|
|
232
|
+
setParams(area: WorkCenterArea, inputs: WorkCenterBootstrapInputs): rxjs.Observable<void>;
|
|
233
|
+
selectCardAndLoad(area: WorkCenterArea, selectedCardKey: string): rxjs.Observable<void>;
|
|
234
|
+
applyTableLazyLoadAndLoad(area: WorkCenterArea, event: any): rxjs.Observable<void> | undefined;
|
|
235
|
+
applyRuntimeFiltersAndLoad(area: WorkCenterArea, runtimeFilters: WorkCenterFilterRule[]): rxjs.Observable<void>;
|
|
236
|
+
loadRuntime(area: WorkCenterArea, reason?: WorkCenterLoadReason): rxjs.Observable<void>;
|
|
237
|
+
private toPositiveInt;
|
|
238
|
+
private toSortFromLazyEvent;
|
|
239
|
+
private isSameSort;
|
|
240
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WorkCenterFacade, never>;
|
|
241
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<WorkCenterFacade>;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
declare class WorkCenterState {
|
|
245
|
+
private readonly http;
|
|
246
|
+
static getState(state: WorkCenterStateModel): WorkCenterStateModel;
|
|
247
|
+
static activeArea(state: WorkCenterStateModel): WorkCenterArea;
|
|
248
|
+
static activeSnapshot(activeArea: WorkCenterArea, state: WorkCenterStateModel): WorkCenterAreaState;
|
|
249
|
+
static context(snapshot: WorkCenterAreaState): _masterteam_work_center.WorkCenterContext;
|
|
250
|
+
static menuItems(snapshot: WorkCenterAreaState): _masterteam_components_types_masterteam_components_client_page_menu.ClientPageMenuItem[];
|
|
251
|
+
static rows(snapshot: WorkCenterAreaState): Record<string, unknown>[];
|
|
252
|
+
static columns(snapshot: WorkCenterAreaState): _masterteam_components_types_masterteam_components_table.ColumnDef[];
|
|
253
|
+
static kpis(snapshot: WorkCenterAreaState): _masterteam_components_types_masterteam_components_statistic_card.StatisticCardData[];
|
|
254
|
+
static runtimeFilterSchema(snapshot: WorkCenterAreaState): WorkCenterRuntimeFilterSchema | null;
|
|
255
|
+
static totalCount(snapshot: WorkCenterAreaState): number;
|
|
256
|
+
static warnings(snapshot: WorkCenterAreaState): _masterteam_work_center.WorkCenterRuntimeWarningDto[];
|
|
257
|
+
static getLoadingActive(state: WorkCenterStateModel): string[];
|
|
258
|
+
static getErrors(state: WorkCenterStateModel): Record<string, string | null>;
|
|
259
|
+
enterArea(ctx: StateContext<WorkCenterStateModel>, action: EnterArea): void;
|
|
260
|
+
hydrateFromContext(ctx: StateContext<WorkCenterStateModel>, action: HydrateFromContext): void;
|
|
261
|
+
setParams(ctx: StateContext<WorkCenterStateModel>, action: SetParams): rxjs.Observable<void> | undefined;
|
|
262
|
+
loadRuntime(ctx: StateContext<WorkCenterStateModel>, action: LoadRuntime): rxjs.Observable<WorkCenterRuntimeResponseData>;
|
|
263
|
+
private getRuntime;
|
|
264
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<WorkCenterState, never>;
|
|
265
|
+
static ɵprov: _angular_core.ɵɵInjectableDeclaration<WorkCenterState>;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
declare const APP_STATES: (typeof WorkCenterState)[];
|
|
269
|
+
|
|
270
|
+
export { APP_STATES, EnterArea, HydrateFromContext, LoadRuntime, SetParams, WORK_CENTER_MAX_FILTERS, WORK_CENTER_MAX_PAGE_SIZE, WORK_CENTER_MAX_SORT, WORK_CENTER_QUERY_VERSION, WorkCenterActionKey, WorkCenterFacade, WorkCenterPage, WorkCenterState };
|
|
271
|
+
export type { ApiEnvelope, TranslatableDto, WorkCenterArea, WorkCenterAreaState, WorkCenterBootstrapInputs, WorkCenterColumnsConfig, WorkCenterContext, WorkCenterFilterOperator, WorkCenterFilterRule, WorkCenterHydratePatch, WorkCenterLoadReason, WorkCenterRuntimeCard, WorkCenterRuntimeFilterSchema, WorkCenterRuntimeOperatorOption, WorkCenterRuntimePagination, WorkCenterRuntimeProperty, WorkCenterRuntimeRequest, WorkCenterRuntimeResponseData, WorkCenterRuntimeSelectedCard, WorkCenterRuntimeStatsItem, WorkCenterRuntimeWarningDto, WorkCenterSortRule, WorkCenterStateModel };
|