inviton-powerduck 0.0.72 → 0.0.73

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.
@@ -13,303 +13,303 @@ import { IValidation, ValidationState } from './static-wrappers/interfaces/valid
13
13
  import ScrollUtils from "./scroll-utils";
14
14
 
15
15
  export abstract class PowerduckViewModelBase extends Vue {
16
- blockRoot: boolean = true;
17
- authorized: boolean = true;
18
- v$: Validation;
19
-
20
- constructor(optionBuilder: OptionBuilder, vueInstance: any) {
21
- super(optionBuilder, vueInstance);
22
- this.v$ = useVuelidate({
23
- $scope: vueInstance
24
- }) as any as Validation;
25
- }
26
-
27
- /**
28
- * Current interface language
29
- */
30
- get appLanguage(): Language {
31
- return PowerduckState.getCurrentLanguage();
32
- }
33
-
34
- /**
35
- * Try GET data from Inviton API enpoint
36
- */
37
- public async tryGetDataByArgs<TData, TArgs = {}>(args: TryCallApiArgs<TData, TArgs>): Promise<TData> {
38
- return this.tryCallApiByArgs(args, false);
39
- }
40
-
41
- /**
42
- * Try POST data to Inviton API endpoint
43
- */
44
- public async tryPostDataByArgs<TData, TArgs>(args: TryCallApiArgs<TData, TArgs>): Promise<TryPostApiResponse<TData>> {
45
- var retVal = await this.tryCallApiByArgs(args, true);
46
- if (retVal != null && retVal["ajaxErr"] != null) {
47
- return {
48
- data: null as any,
49
- error: retVal["ajaxErr"],
50
- result: TryCallApiResult.Error,
51
- };
52
- } else {
53
- return {
54
- data: retVal,
55
- error: null as any,
56
- result: TryCallApiResult.Success,
57
- };
58
- }
59
- }
60
-
61
- /**
62
- * Try PATCH data to Inviton API endpoint
63
- * just decorator
64
- */
65
- public async tryPatchDataByArgs<TData, TArgs>(args: TryCallApiArgs<TData, TArgs>): Promise<TryPatchApiResponse<TData>> {
66
- return await this.tryPostDataByArgs(args);
67
- }
68
-
69
- public async tryDeleteDataByArgs<TData, TArgs>(args: TryCallApiArgs<TData, TArgs>): Promise<TData> {
70
- return this.tryCallApiByArgs(args, false);
71
- }
72
-
73
- private async tryCallApiByArgs<TData, TArgs>(args: TryCallApiArgs<TData, TArgs>, includeError: boolean): Promise<TData> {
74
- var retVal: TData;
75
- let handle: any = null;
76
-
77
- if (args.blockRoot != false) {
78
- handle = setTimeout(() => {
79
- this.blockRoot = true;
80
- }, 850);
81
- }
82
-
83
- var apiMethod = args.apiMethod as any;
84
- var promise = apiMethod(args.requestArgs, args.timeout);
85
-
86
- try {
87
- retVal = await promise;
88
- } catch (e: any) {
89
- let err: AjaxError = e;
90
-
91
- if (args.blockRoot != false) {
92
- this.blockRoot = false;
93
- }
94
-
95
- if (e == "not authorized, token expired") {
96
- err = {
97
- authorized: false,
98
- responseText: PowerduckState.getResourceValue('loginExpired'),
99
- } as any;
100
- }
101
-
102
- if (err.authorized == false || e == "not authorized, token expired") {
103
- (window as any).loginModalRootInstance.show();
104
- }
105
-
106
- if (!err.authorized && args.toggleAuthorization) {
107
- this.authorized = err.authorized;
108
- }
109
-
110
- if (args.showError != false) {
111
- let parsedMsg = PowerduckState.parseErrorMessage(err.responseText);
112
- if (!isNullOrEmpty(parsedMsg)) {
113
- this.showErrorMessage(parsedMsg);
114
- } else if (err.responseText) {
115
- this.showErrorMessage(err.responseText);
116
- } else if ((err as any).message) {
117
- this.showErrorMessage((err as any).message);
118
- }
119
- }
120
-
121
- if (includeError) {
122
- retVal = {
123
- ajaxErr: err,
124
- } as any;
125
- } else {
126
- retVal = null as any;
127
- }
128
- }
129
-
130
- if (args.blockRoot != false) {
131
- try {
132
- clearTimeout(handle);
133
- } catch (error) { }
134
-
135
- if (this.blockRoot == true) {
136
- this.blockRoot = false;
137
- }
138
- }
139
-
140
- return retVal;
141
- }
142
-
143
- /**
144
- * Get children components of given type
145
- *
146
- * @param typeName Name of the type
147
- */
148
- getChildrenByType<T>(typeName: string): Array<T> {
149
- return PortalUtils.getChildrenByType(this, typeName);
150
- }
151
-
152
- /**
153
- * Displays unobtrusive error message
154
- * @param errMsg Error message
155
- */
156
- showErrorMessage(errMsg: string): void {
157
- NotificationProvider.showErrorMessage(errMsg);
158
- }
159
-
160
- /**
161
- * Displays unobtrusive success message
162
- * @param successMsg Success message
163
- */
164
- showSuccessMessage(successMsg: string): void {
165
- NotificationProvider.showSuccessMessage(successMsg);
166
- }
167
-
168
- /**
169
- * Parse variable into number
170
- * @param val
171
- * @param defaultValue
172
- */
173
- getNumericValue(val: any, defaultValue?: number) {
174
- if (val != null) {
175
- try {
176
- val = Number(val);
177
- if (isNaN(val)) {
178
- val = defaultValue;
179
- }
180
- } catch (e) {
181
- val = defaultValue;
182
- }
183
- } else {
184
- val = defaultValue;
185
- }
186
-
187
- return val;
188
- }
189
-
190
- /**
191
- * Validates current viewModel state based on given valdiation ruleset
192
- */
193
- async validate(showErrorMessage?: boolean, silent?: boolean): Promise<boolean> {
194
- if (localStorage.getItem("disableValidation") == "1") {
195
- return true;
196
- }
197
-
198
- if (this.v$ == null) {
199
- throw "Validation rules not specified, has to be specified in @Component declaration!";
200
- }
201
-
202
- var isInvalid = !(await this.v$.$validate());
203
- if (isInvalid) {
204
- if (showErrorMessage != false) {
205
- this.showValidationErrorMessage();
206
- }
207
-
208
- if (silent != true) {
209
- this.validationIncludeDirty = true;
210
- this.$nextTick(() => {
211
- this.scrollToFirstPossibleError($(this.unwrapRootElement()));
212
- });
213
- }
214
- }
215
-
216
- return !isInvalid;
217
- }
218
-
219
- unwrapRootElement(): HTMLElement {
220
- if ((this.$el as any).$getChildSlots != null) {
221
- return (((this.$el as any).$getChildSlots() || [])[0]?.el || this.$el) as any;
222
- }
223
-
224
- return this.$el as any;
225
- }
226
-
227
- showValidationErrorMessage() {
228
- this.showErrorMessage(PowerduckState.getResourceValue('errorsOnForm'));
229
- }
230
-
231
- scrollToFirstPossibleError(context: JQuery) {
232
- ScrollUtils.scrollToFirstPossibleError(context);
233
- }
234
-
235
- /**
236
- * Scrolls to element
237
- * @param elem
238
- */
239
- scrollToElem(elem: typeof Vue | Element | typeof Vue[] | Element[], mobileOffset?: boolean | number, mobileOffsetSmoothing?: boolean, animated?: boolean, instant?: boolean): void {
240
- ScrollUtils.scrollToElem(elem, mobileOffset, mobileOffsetSmoothing, animated, instant);
241
- }
242
-
243
- /**
244
- * Scrolls to position
245
- * @param elem
246
- */
247
- scrollToPos(position: number, context?: JQuery, animated?: boolean, instant?: boolean): void {
248
- ScrollUtils.scrollToPos(position, context, animated, instant);
249
- }
250
-
251
- /**
252
- * Determines if DIRTY should be included in validation
253
- */
254
- validationIncludeDirty: boolean = false;
255
-
256
- /**
257
- * Obtains validation state of given property
258
- * @param valProp Validation property
259
- */
260
- validationStateOf(valProp: IValidation | IValidation[], customMessage?: string): ValidationState {
261
- let retVal: ValidationState = null as any;
262
- if (!PortalUtils.isArray(valProp)) {
263
- retVal = ValidationHelper.getValidationDisplayState(valProp as any, this.validationIncludeDirty);
264
- } else {
265
- let validationResult: ValidationState;
266
- for (let i = 0, len = (valProp as IValidation[]).length; i < len; i++) {
267
- validationResult = ValidationHelper.getValidationDisplayState(valProp[i], this.validationIncludeDirty);
268
- if (!validationResult.valid) {
269
- retVal = validationResult;
270
- break;
271
- }
272
- }
273
- }
274
-
275
- if (retVal?.valid == false) {
276
- if (!isNullOrEmpty(customMessage as any)) {
277
- retVal = retVal || {} as any;
278
- retVal.errorMessage = customMessage as string;
279
- }
280
- }
281
-
282
- return retVal;
283
- }
284
-
285
- /**
286
- * Resets validation state of the viewModel
287
- */
288
- resetValidation() {
289
- ValidationHelper.resetValidation(this);
290
- this.validationIncludeDirty = false;
291
- }
16
+ blockRoot: boolean = true;
17
+ authorized: boolean = true;
18
+ v$: Validation;
19
+
20
+ constructor(optionBuilder: OptionBuilder, vueInstance: any) {
21
+ super(optionBuilder, vueInstance);
22
+ this.v$ = useVuelidate({
23
+ $scope: vueInstance
24
+ }) as any as Validation;
25
+ }
26
+
27
+ /**
28
+ * Current interface language
29
+ */
30
+ get appLanguage(): Language {
31
+ return PowerduckState.getCurrentLanguage();
32
+ }
33
+
34
+ /**
35
+ * Try GET data from Inviton API enpoint
36
+ */
37
+ public async tryGetDataByArgs<TData, TArgs = {}>(args: TryCallApiArgs<TData, TArgs>): Promise<TData> {
38
+ return this.tryCallApiByArgs(args, false);
39
+ }
40
+
41
+ /**
42
+ * Try POST data to Inviton API endpoint
43
+ */
44
+ public async tryPostDataByArgs<TData, TArgs>(args: TryCallApiArgs<TData, TArgs>): Promise<TryPostApiResponse<TData>> {
45
+ var retVal = await this.tryCallApiByArgs(args, true);
46
+ if (retVal != null && retVal["ajaxErr"] != null) {
47
+ return {
48
+ data: null as any,
49
+ error: retVal["ajaxErr"],
50
+ result: TryCallApiResult.Error,
51
+ };
52
+ } else {
53
+ return {
54
+ data: retVal,
55
+ error: null as any,
56
+ result: TryCallApiResult.Success,
57
+ };
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Try PATCH data to Inviton API endpoint
63
+ * just decorator
64
+ */
65
+ public async tryPatchDataByArgs<TData, TArgs>(args: TryCallApiArgs<TData, TArgs>): Promise<TryPatchApiResponse<TData>> {
66
+ return await this.tryPostDataByArgs(args);
67
+ }
68
+
69
+ public async tryDeleteDataByArgs<TData, TArgs>(args: TryCallApiArgs<TData, TArgs>): Promise<TData> {
70
+ return this.tryCallApiByArgs(args, false);
71
+ }
72
+
73
+ private async tryCallApiByArgs<TData, TArgs>(args: TryCallApiArgs<TData, TArgs>, includeError: boolean): Promise<TData> {
74
+ var retVal: TData;
75
+ let handle: any = null;
76
+
77
+ if (args.blockRoot != false) {
78
+ handle = setTimeout(() => {
79
+ this.blockRoot = true;
80
+ }, 850);
81
+ }
82
+
83
+ var apiMethod = args.apiMethod as any;
84
+ var promise = apiMethod(args.requestArgs, args.timeout);
85
+
86
+ try {
87
+ retVal = await promise;
88
+ } catch (e: any) {
89
+ let err: AjaxError = e;
90
+
91
+ if (args.blockRoot != false) {
92
+ this.blockRoot = false;
93
+ }
94
+
95
+ if (e == "not authorized, token expired") {
96
+ err = {
97
+ authorized: false,
98
+ responseText: PowerduckState.getResourceValue('loginExpired'),
99
+ } as any;
100
+ }
101
+
102
+ if (err.authorized == false || e == "not authorized, token expired") {
103
+ (window as any).loginModalRootInstance.show();
104
+ }
105
+
106
+ if (!err.authorized && args.toggleAuthorization) {
107
+ this.authorized = err.authorized;
108
+ }
109
+
110
+ if (args.showError != false) {
111
+ let parsedMsg = PowerduckState.parseErrorMessage(err.responseText);
112
+ if (!isNullOrEmpty(parsedMsg)) {
113
+ this.showErrorMessage(parsedMsg);
114
+ } else if (err.responseText) {
115
+ this.showErrorMessage(err.responseText);
116
+ } else if ((err as any).message) {
117
+ this.showErrorMessage((err as any).message);
118
+ }
119
+ }
120
+
121
+ if (includeError) {
122
+ retVal = {
123
+ ajaxErr: err,
124
+ } as any;
125
+ } else {
126
+ retVal = null as any;
127
+ }
128
+ }
129
+
130
+ if (args.blockRoot != false) {
131
+ try {
132
+ clearTimeout(handle);
133
+ } catch (error) { }
134
+
135
+ if (this.blockRoot == true) {
136
+ this.blockRoot = false;
137
+ }
138
+ }
139
+
140
+ return retVal;
141
+ }
142
+
143
+ /**
144
+ * Get children components of given type
145
+ *
146
+ * @param typeName Name of the type
147
+ */
148
+ getChildrenByType<T>(typeName: string): Array<T> {
149
+ return PortalUtils.getChildrenByType(this, typeName);
150
+ }
151
+
152
+ /**
153
+ * Displays unobtrusive error message
154
+ * @param errMsg Error message
155
+ */
156
+ showErrorMessage(errMsg: string): void {
157
+ NotificationProvider.showErrorMessage(errMsg);
158
+ }
159
+
160
+ /**
161
+ * Displays unobtrusive success message
162
+ * @param successMsg Success message
163
+ */
164
+ showSuccessMessage(successMsg: string): void {
165
+ NotificationProvider.showSuccessMessage(successMsg);
166
+ }
167
+
168
+ /**
169
+ * Parse variable into number
170
+ * @param val
171
+ * @param defaultValue
172
+ */
173
+ getNumericValue(val: any, defaultValue?: number) {
174
+ if (val != null) {
175
+ try {
176
+ val = Number(val);
177
+ if (isNaN(val)) {
178
+ val = defaultValue;
179
+ }
180
+ } catch (e) {
181
+ val = defaultValue;
182
+ }
183
+ } else {
184
+ val = defaultValue;
185
+ }
186
+
187
+ return val;
188
+ }
189
+
190
+ /**
191
+ * Validates current viewModel state based on given valdiation ruleset
192
+ */
193
+ async validate(showErrorMessage?: boolean, silent?: boolean): Promise<boolean> {
194
+ if (localStorage.getItem("disableValidation") == "1") {
195
+ return true;
196
+ }
197
+
198
+ if (this.v$ == null) {
199
+ throw "Validation rules not specified, has to be specified in @Component declaration!";
200
+ }
201
+
202
+ var isInvalid = !(await this.v$.$validate());
203
+ if (isInvalid) {
204
+ if (showErrorMessage != false) {
205
+ this.showValidationErrorMessage();
206
+ }
207
+
208
+ if (silent != true) {
209
+ this.validationIncludeDirty = true;
210
+ this.$nextTick(() => {
211
+ this.scrollToFirstPossibleError($(this.unwrapRootElement()));
212
+ });
213
+ }
214
+ }
215
+
216
+ return !isInvalid;
217
+ }
218
+
219
+ unwrapRootElement(): HTMLElement {
220
+ if ((this.$el as any).$getChildSlots != null) {
221
+ return (((this.$el as any).$getChildSlots() || [])[0]?.el || this.$el) as any;
222
+ }
223
+
224
+ return this.$el as any;
225
+ }
226
+
227
+ showValidationErrorMessage() {
228
+ this.showErrorMessage(PowerduckState.getResourceValue('errorsOnForm'));
229
+ }
230
+
231
+ scrollToFirstPossibleError(context: JQuery) {
232
+ ScrollUtils.scrollToFirstPossibleError(context);
233
+ }
234
+
235
+ /**
236
+ * Scrolls to element
237
+ * @param elem
238
+ */
239
+ scrollToElem(elem: typeof Vue | Element | typeof Vue[] | Element[], mobileOffset?: boolean | number, mobileOffsetSmoothing?: boolean, animated?: boolean, instant?: boolean): void {
240
+ ScrollUtils.scrollToElem(elem, mobileOffset, mobileOffsetSmoothing, animated, instant);
241
+ }
242
+
243
+ /**
244
+ * Scrolls to position
245
+ * @param elem
246
+ */
247
+ scrollToPos(position: number, context?: JQuery, animated?: boolean, instant?: boolean): void {
248
+ ScrollUtils.scrollToPos(position, context, animated, instant);
249
+ }
250
+
251
+ /**
252
+ * Determines if DIRTY should be included in validation
253
+ */
254
+ validationIncludeDirty: boolean = false;
255
+
256
+ /**
257
+ * Obtains validation state of given property
258
+ * @param valProp Validation property
259
+ */
260
+ validationStateOf(valProp: IValidation | IValidation[], customMessage?: string): ValidationState {
261
+ let retVal: ValidationState = null as any;
262
+ if (!PortalUtils.isArray(valProp)) {
263
+ retVal = ValidationHelper.getValidationDisplayState(valProp as any, this.validationIncludeDirty);
264
+ } else {
265
+ let validationResult: ValidationState;
266
+ for (let i = 0, len = (valProp as IValidation[]).length; i < len; i++) {
267
+ validationResult = ValidationHelper.getValidationDisplayState(valProp[i], this.validationIncludeDirty);
268
+ if (!validationResult.valid) {
269
+ retVal = validationResult;
270
+ break;
271
+ }
272
+ }
273
+ }
274
+
275
+ if (retVal?.valid == false) {
276
+ if (!isNullOrEmpty(customMessage as any)) {
277
+ retVal = retVal || {} as any;
278
+ retVal.errorMessage = customMessage as string;
279
+ }
280
+ }
281
+
282
+ return retVal;
283
+ }
284
+
285
+ /**
286
+ * Resets validation state of the viewModel
287
+ */
288
+ resetValidation() {
289
+ ValidationHelper.resetValidation(this);
290
+ this.validationIncludeDirty = false;
291
+ }
292
292
  }
293
293
 
294
294
  interface TryCallApiArgs<TData, TArgs> {
295
- apiMethod: (data?: TArgs) => Promise<TData>;
296
- timeout?: number;
297
- requestArgs?: TArgs;
298
- showError?: boolean;
299
- blockRoot?: boolean;
300
- toggleAuthorization?: boolean;
301
- toggleAuthorizationOnNullUser?: boolean;
295
+ apiMethod: (data?: TArgs) => Promise<TData>;
296
+ timeout?: number;
297
+ requestArgs?: TArgs;
298
+ showError?: boolean;
299
+ blockRoot?: boolean;
300
+ toggleAuthorization?: boolean;
301
+ toggleAuthorizationOnNullUser?: boolean;
302
302
  }
303
303
 
304
304
  export interface TryPostApiResponse<TData> {
305
- data: TData;
306
- result: TryCallApiResult;
307
- error: AjaxError;
305
+ data: TData;
306
+ result: TryCallApiResult;
307
+ error: AjaxError;
308
308
  }
309
309
 
310
310
  export interface TryPatchApiResponse<TData> extends TryPostApiResponse<TData> { }
311
311
 
312
312
  interface PortalActionMessage {
313
- action: string;
314
- data: any;
313
+ action: string;
314
+ data: any;
315
315
  }
@@ -0,0 +1,44 @@
1
+ export default class KeyboardOpenTracker {
2
+ static bind() {
3
+ if ((window as any)._keyboardOpenTrackerBound == true) {
4
+ return;
5
+ }
6
+
7
+ (window as any)._keyboardOpenTrackerBound = true;
8
+
9
+ const getOrientation = () => {
10
+ return window.screen.width > window.screen.height ? 'landscape' : 'portrait';
11
+ }
12
+
13
+ const getScreenHeight = () => {
14
+ return window.screen.height; // Constant physical screen height
15
+ }
16
+
17
+ let lastOrientation = getOrientation();
18
+ const handleResize = () => {
19
+ const currentOrientation = getOrientation();
20
+ const currentInnerHeight = window.innerHeight;
21
+ const screenHeight = getScreenHeight();
22
+
23
+ // Different thresholds for portrait/landscape
24
+ const THRESHOLD_PORTRAIT = 150;
25
+ const THRESHOLD_LANDSCAPE = 100;
26
+
27
+ const isPortrait = currentOrientation === 'portrait';
28
+ const threshold = isPortrait ? THRESHOLD_PORTRAIT : THRESHOLD_LANDSCAPE;
29
+
30
+ // Reset baseline when orientation changes
31
+ if (currentOrientation !== lastOrientation) {
32
+ lastOrientation = currentOrientation;
33
+ console.log(`[Resize] Orientation changed → ${currentOrientation}`);
34
+ }
35
+
36
+ const heightDiff = screenHeight - currentInnerHeight;
37
+ const isKeyboardOpen = heightDiff > threshold;
38
+ document.body.classList.toggle('powerduck-keyboard-open', isKeyboardOpen);
39
+ }
40
+
41
+ window.addEventListener('resize', handleResize);
42
+ handleResize(); // Run initially
43
+ }
44
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "inviton-powerduck",
3
- "version": "0.0.72",
3
+ "version": "0.0.73",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "build": " vite build && vue-tsc --declaration --emitDeclarationOnly",