@performant-software/shared-components 0.5.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.
- package/LICENSE +21 -0
- package/README.md +0 -0
- package/build/index.js +2 -0
- package/build/index.js.map +1 -0
- package/build/main.css +11 -0
- package/index.js +1 -0
- package/package.json +36 -0
- package/src/api/Attachments.js +28 -0
- package/src/api/BaseService.js +127 -0
- package/src/api/BaseTransform.js +55 -0
- package/src/api/FormDataTransform.js +30 -0
- package/src/api/NestedAttributesTransform.js +63 -0
- package/src/components/EditContainer.css +0 -0
- package/src/components/EditContainer.js +448 -0
- package/src/components/GoogleAnalytics.css +0 -0
- package/src/components/GoogleAnalytics.js +118 -0
- package/src/components/GoogleScript.js +5 -0
- package/src/components/InfiniteScroll.css +1 -0
- package/src/components/InfiniteScroll.js +120 -0
- package/src/components/Keyboard.css +11 -0
- package/src/components/Keyboard.js +55 -0
- package/src/i18n/en.json +204 -0
- package/src/i18n/i18n.js +24 -0
- package/src/index.js +34 -0
- package/src/utils/Browser.js +8 -0
- package/src/utils/Calendar.js +232 -0
- package/src/utils/Date.js +10 -0
- package/src/utils/DragDrop.js +17 -0
- package/src/utils/Element.js +36 -0
- package/src/utils/Map.js +27 -0
- package/src/utils/Object.js +114 -0
- package/src/utils/String.js +20 -0
- package/src/utils/Timer.js +32 -0
- package/src/utils/Utility.js +14 -0
- package/test/api/Attachments.spec.js +32 -0
- package/types/api/Attachments.js.flow +28 -0
- package/types/api/BaseService.js.flow +127 -0
- package/types/api/BaseTransform.js.flow +55 -0
- package/types/api/FormDataTransform.js.flow +30 -0
- package/types/api/NestedAttributesTransform.js.flow +63 -0
- package/types/components/EditContainer.js.flow +448 -0
- package/types/components/GoogleAnalytics.js.flow +118 -0
- package/types/components/GoogleScript.js.flow +5 -0
- package/types/components/InfiniteScroll.js.flow +120 -0
- package/types/components/Keyboard.js.flow +55 -0
- package/types/i18n/i18n.js.flow +24 -0
- package/types/index.js.flow +34 -0
- package/types/utils/Browser.js.flow +8 -0
- package/types/utils/Calendar.js.flow +232 -0
- package/types/utils/Date.js.flow +10 -0
- package/types/utils/DragDrop.js.flow +17 -0
- package/types/utils/Element.js.flow +36 -0
- package/types/utils/Map.js.flow +27 -0
- package/types/utils/Object.js.flow +114 -0
- package/types/utils/String.js.flow +20 -0
- package/types/utils/Timer.js.flow +32 -0
- package/types/utils/Utility.js.flow +14 -0
- package/webpack.config.js +3 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { useEffect, useRef } from 'react';
|
|
4
|
+
import Keyboard from 'simple-keyboard';
|
|
5
|
+
import './Keyboard.css';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
layout: any,
|
|
9
|
+
onChange: (value: string) => void,
|
|
10
|
+
value: string,
|
|
11
|
+
keyboardClass: string,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const KEY_CAPS_LOCK = '{lock}';
|
|
15
|
+
const KEY_SHIFT = '{shift}';
|
|
16
|
+
|
|
17
|
+
const LAYOUT_DEFAULT = 'default';
|
|
18
|
+
const LAYOUT_SHIFT = 'shift';
|
|
19
|
+
|
|
20
|
+
const KeyboardSimple = (props: Props) => {
|
|
21
|
+
const keyboardRef = useRef();
|
|
22
|
+
|
|
23
|
+
// Toggles the layout name for Shift and CapsLock keys.
|
|
24
|
+
const onKeyPress = (value) => {
|
|
25
|
+
const isCaps = value === KEY_CAPS_LOCK || value === KEY_SHIFT;
|
|
26
|
+
|
|
27
|
+
if (isCaps && keyboardRef.current && keyboardRef.current.options.layoutName === LAYOUT_SHIFT) {
|
|
28
|
+
keyboardRef.current.setOptions({ layoutName: LAYOUT_DEFAULT });
|
|
29
|
+
} else if (isCaps && keyboardRef.current && keyboardRef.current.options.layoutName !== LAYOUT_SHIFT) {
|
|
30
|
+
keyboardRef.current.setOptions({ layoutName: LAYOUT_SHIFT });
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Sets up the keyboard reference and the initial value when the component is first rendered.
|
|
35
|
+
useEffect(() => {
|
|
36
|
+
const { layout, onChange } = props;
|
|
37
|
+
keyboardRef.current = new Keyboard(`.${props.keyboardClass}`, { ...layout, onChange, onKeyPress });
|
|
38
|
+
keyboardRef.current.setInput(props.value);
|
|
39
|
+
}, []);
|
|
40
|
+
|
|
41
|
+
// Sets the keyboard value when the value property changes.
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
if (keyboardRef.current) {
|
|
44
|
+
keyboardRef.current.setInput(props.value);
|
|
45
|
+
}
|
|
46
|
+
}, [props.value]);
|
|
47
|
+
|
|
48
|
+
return <div className={props.keyboardClass} />;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
KeyboardSimple.defaultProps = {
|
|
52
|
+
keyboardClass: 'simple-keyboard'
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export default KeyboardSimple;
|
package/src/i18n/en.json
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
{
|
|
2
|
+
"AccordionList": {
|
|
3
|
+
"deleteContent": "Are you sure you want to remove this record?",
|
|
4
|
+
"deleteHeader": "Confirm Remove",
|
|
5
|
+
"record": "Record",
|
|
6
|
+
"record_plural": "Records"
|
|
7
|
+
},
|
|
8
|
+
"AccordionSelector": {
|
|
9
|
+
"title": "Select Items"
|
|
10
|
+
},
|
|
11
|
+
"Common": {
|
|
12
|
+
"buttons": {
|
|
13
|
+
"add": "Add",
|
|
14
|
+
"cancel": "Cancel",
|
|
15
|
+
"clear": "Clear",
|
|
16
|
+
"edit": "Edit",
|
|
17
|
+
"ok": "OK",
|
|
18
|
+
"save": "Save"
|
|
19
|
+
},
|
|
20
|
+
"errors": {
|
|
21
|
+
"title": "Oops!"
|
|
22
|
+
},
|
|
23
|
+
"messages": {
|
|
24
|
+
"error": {
|
|
25
|
+
"header": "Oops!"
|
|
26
|
+
},
|
|
27
|
+
"loading": "Loading",
|
|
28
|
+
"save": {
|
|
29
|
+
"content": "Your changes have been saved.",
|
|
30
|
+
"header": "Success!"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"EditContainer": {
|
|
35
|
+
"errors": {
|
|
36
|
+
"general": "Something went wrong while saving the record. Please make sure all required fields are filled out.",
|
|
37
|
+
"required": "The {{key}} field is required.",
|
|
38
|
+
"system": "A system error occurred while saving the record. Please contact your system administrator.",
|
|
39
|
+
"unique": "A record with the {{key}} \"{{value}}\" already exists."
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"DataTable": {
|
|
43
|
+
"actions": {
|
|
44
|
+
"copy": {
|
|
45
|
+
"content": "Creates an editable copy to be saved as a new record",
|
|
46
|
+
"title": "Copy"
|
|
47
|
+
},
|
|
48
|
+
"delete": {
|
|
49
|
+
"content": "Removes the record, permanently",
|
|
50
|
+
"title": "Remove"
|
|
51
|
+
},
|
|
52
|
+
"edit": {
|
|
53
|
+
"content": "Opens the modal to edit the record",
|
|
54
|
+
"title": "Edit"
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
"columns": {
|
|
58
|
+
"actions": "Actions",
|
|
59
|
+
"select": "Select"
|
|
60
|
+
},
|
|
61
|
+
"loading": "Loading"
|
|
62
|
+
},
|
|
63
|
+
"EditProvider": {
|
|
64
|
+
"errors": {
|
|
65
|
+
"general": "Something went wrong while saving the record. Please make sure all required fields are filled out.",
|
|
66
|
+
"required": "The {{key}} field is required.",
|
|
67
|
+
"unique": "A record with the {{key}} \"{{value}}\" already exists."
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"FileUpload": {
|
|
71
|
+
"add": "<0>Add files</0> or drop files here",
|
|
72
|
+
"errors": {
|
|
73
|
+
"fileType": "Unable to upload {{name}} because {{type}} files are not allowed.",
|
|
74
|
+
"maxSize": "Unable to upload {{name}} because it exceeds 10 MB."
|
|
75
|
+
}
|
|
76
|
+
},
|
|
77
|
+
"FileUploadModal": {
|
|
78
|
+
"errors": {
|
|
79
|
+
"required": "{{filename}} - The following fields are required: {{fields}}"
|
|
80
|
+
},
|
|
81
|
+
"loader": "Uploading files...",
|
|
82
|
+
"title": "Upload Files"
|
|
83
|
+
},
|
|
84
|
+
"FuzzyDate": {
|
|
85
|
+
"accuracy": {
|
|
86
|
+
"date": "Date",
|
|
87
|
+
"month": "Month",
|
|
88
|
+
"year": "Year"
|
|
89
|
+
},
|
|
90
|
+
"buttons": {
|
|
91
|
+
"addRange": "Add Range",
|
|
92
|
+
"removeRange": "Remove Range"
|
|
93
|
+
},
|
|
94
|
+
"labels": {
|
|
95
|
+
"accuracy": "Accuracy",
|
|
96
|
+
"date": "Date",
|
|
97
|
+
"description": "Description",
|
|
98
|
+
"month": "Month",
|
|
99
|
+
"year": "Year"
|
|
100
|
+
},
|
|
101
|
+
"title": "Fuzzy Date"
|
|
102
|
+
},
|
|
103
|
+
"ItemList": {
|
|
104
|
+
"actions": {
|
|
105
|
+
"copy": "Copy",
|
|
106
|
+
"delete": "Remove",
|
|
107
|
+
"edit": "Edit"
|
|
108
|
+
},
|
|
109
|
+
"buttons": {
|
|
110
|
+
"clear": "Clear selected",
|
|
111
|
+
"deselectAll": "Deselect all",
|
|
112
|
+
"selectAll": "Select all"
|
|
113
|
+
}
|
|
114
|
+
},
|
|
115
|
+
"KeyboardField": {
|
|
116
|
+
"labels": {
|
|
117
|
+
"hideKeyboard": "Hide Keyboard",
|
|
118
|
+
"showKeyboard": "Show Keyboard"
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"LazyDocument": {
|
|
122
|
+
"buttons": {
|
|
123
|
+
"download": "Download"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"LazyImage": {
|
|
127
|
+
"buttons": {
|
|
128
|
+
"view": "View image"
|
|
129
|
+
}
|
|
130
|
+
},
|
|
131
|
+
"LazyVideo": {
|
|
132
|
+
"buttons": {
|
|
133
|
+
"play": "Play video"
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
"List": {
|
|
137
|
+
"buttons": {
|
|
138
|
+
"add": "Add",
|
|
139
|
+
"deleteAll": "Delete all"
|
|
140
|
+
},
|
|
141
|
+
"deleteAllContent": "Are you sure you want to remove all records? This action cannot be undone.",
|
|
142
|
+
"deleteAllHeader": "Confirm Remove All",
|
|
143
|
+
"deleteContent": "Are you sure you want to remove this record?",
|
|
144
|
+
"deleteHeader": "Confirm Remove",
|
|
145
|
+
"emptyList": "No matching records found.",
|
|
146
|
+
"emptyListAdd": "You haven't added any yet. Click <1><0><0></0><1></1></0></1> to get started.",
|
|
147
|
+
"labels": {
|
|
148
|
+
"perPage": "Show {{perPage}}"
|
|
149
|
+
},
|
|
150
|
+
"record": "Record",
|
|
151
|
+
"record_plural": "Records"
|
|
152
|
+
},
|
|
153
|
+
"ListFilters": {
|
|
154
|
+
"buttons": {
|
|
155
|
+
"add": "Add",
|
|
156
|
+
"reset": "Reset filters"
|
|
157
|
+
},
|
|
158
|
+
"operators": {
|
|
159
|
+
"contain": "Contains",
|
|
160
|
+
"empty": "Is empty",
|
|
161
|
+
"equal": "Equals",
|
|
162
|
+
"greaterThan": "Is greater than",
|
|
163
|
+
"lessThan": "Is less than",
|
|
164
|
+
"notContain": "Does not contain",
|
|
165
|
+
"notEmpty": "Is not empty",
|
|
166
|
+
"notEqual": "Does not equal"
|
|
167
|
+
},
|
|
168
|
+
"title": "Filters"
|
|
169
|
+
},
|
|
170
|
+
"LoginModal": {
|
|
171
|
+
"buttonCancel": "Cancel",
|
|
172
|
+
"buttonLogin": "Login",
|
|
173
|
+
"email": "Email",
|
|
174
|
+
"header": "Login",
|
|
175
|
+
"loginErrorContent": "The username and/or password you entered is invalid. Please double check and try again.",
|
|
176
|
+
"loginErrorHeader": "Invalid Credentials",
|
|
177
|
+
"password": "Password"
|
|
178
|
+
},
|
|
179
|
+
"RemoteDropdown": {
|
|
180
|
+
"labels": {
|
|
181
|
+
"add": "Add",
|
|
182
|
+
"loadMore": "Load more"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
"Selectize": {
|
|
186
|
+
"noRecords": "No matching records."
|
|
187
|
+
},
|
|
188
|
+
"VideoFrameSelector": {
|
|
189
|
+
"buttons": {
|
|
190
|
+
"select": "Select frame"
|
|
191
|
+
},
|
|
192
|
+
"labels": {
|
|
193
|
+
"interval": "Interval: {{count}} second",
|
|
194
|
+
"interval_plural": "Interval: {{count}} seconds"
|
|
195
|
+
},
|
|
196
|
+
"title": "Select Frame"
|
|
197
|
+
},
|
|
198
|
+
"ViewXML": {
|
|
199
|
+
"buttons": {
|
|
200
|
+
"view": "View XML"
|
|
201
|
+
},
|
|
202
|
+
"title": "XML"
|
|
203
|
+
}
|
|
204
|
+
}
|
package/src/i18n/i18n.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import i18next from 'i18next';
|
|
2
|
+
|
|
3
|
+
import en from './en.json';
|
|
4
|
+
|
|
5
|
+
const resources = {
|
|
6
|
+
en: {
|
|
7
|
+
translation: en
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const i18n = i18next.createInstance();
|
|
12
|
+
|
|
13
|
+
i18n
|
|
14
|
+
.init({
|
|
15
|
+
debug: true,
|
|
16
|
+
fallbackLng: 'en',
|
|
17
|
+
lng: 'en',
|
|
18
|
+
interpolation: {
|
|
19
|
+
escapeValue: false,
|
|
20
|
+
},
|
|
21
|
+
resources
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
export default i18n;
|
package/src/index.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
// API
|
|
4
|
+
export { default as Attachments } from './api/Attachments';
|
|
5
|
+
export { default as BaseService } from './api/BaseService';
|
|
6
|
+
export { default as BaseTransform } from './api/BaseTransform';
|
|
7
|
+
export { default as FormDataTransform } from './api/FormDataTransform';
|
|
8
|
+
export { default as NestedAttributesTransform } from './api/NestedAttributesTransform';
|
|
9
|
+
|
|
10
|
+
// Components
|
|
11
|
+
export { default as useEditContainer } from './components/EditContainer';
|
|
12
|
+
export { default as withGoogleAnalytics } from './components/GoogleAnalytics';
|
|
13
|
+
export { default as GoogleScript } from './components/GoogleScript';
|
|
14
|
+
export { default as InfiniteScroll } from './components/InfiniteScroll';
|
|
15
|
+
export { default as Keyboard } from './components/Keyboard';
|
|
16
|
+
|
|
17
|
+
// I18n
|
|
18
|
+
export { default as i18n } from './i18n/i18n';
|
|
19
|
+
|
|
20
|
+
// Utils
|
|
21
|
+
export * as Browser from './utils/Browser';
|
|
22
|
+
export { default as Calendar } from './utils/Calendar';
|
|
23
|
+
export { default as Date } from './utils/Date';
|
|
24
|
+
export { default as useDragDrop } from './utils/DragDrop';
|
|
25
|
+
export { default as Element } from './utils/Element';
|
|
26
|
+
export { default as Map } from './utils/Map';
|
|
27
|
+
export { default as Object } from './utils/Object';
|
|
28
|
+
export { default as String } from './utils/String';
|
|
29
|
+
export { default as Timer } from './utils/Timer';
|
|
30
|
+
export { default as Utility } from './utils/Utility'; // TODO: Rename me
|
|
31
|
+
|
|
32
|
+
// Types
|
|
33
|
+
export type { EditContainerProps as EditModalProps } from './components/EditContainer'; // Backwards compatability
|
|
34
|
+
export type { EditContainerProps } from './components/EditContainer';
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import moment from 'moment-islamic-civil';
|
|
4
|
+
import 'moment/min/locales';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_LOCALE = 'en';
|
|
7
|
+
|
|
8
|
+
const MAX_DAYS_IN_MONTH = 31;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Wrapper class to handle momentJS dates to multiple calendars.
|
|
12
|
+
*/
|
|
13
|
+
class Calendar {
|
|
14
|
+
static Calendars: any;
|
|
15
|
+
static DateFormats: any;
|
|
16
|
+
static Defaults: any;
|
|
17
|
+
|
|
18
|
+
locale: string;
|
|
19
|
+
name: string;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Constructs a new calendar instance for the passed locale and calendar.
|
|
23
|
+
*
|
|
24
|
+
* @param locale
|
|
25
|
+
* @param name
|
|
26
|
+
*/
|
|
27
|
+
constructor(locale: string = DEFAULT_LOCALE, name: string = Calendar.Calendars.gregorian) {
|
|
28
|
+
this.locale = locale;
|
|
29
|
+
this.name = name;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Increments the date by the passed value.
|
|
34
|
+
*
|
|
35
|
+
* @param date
|
|
36
|
+
* @param value
|
|
37
|
+
*
|
|
38
|
+
* @returns {*}
|
|
39
|
+
*/
|
|
40
|
+
addDate(date: Date, value: number) {
|
|
41
|
+
const m = this.moment(date);
|
|
42
|
+
return this.isHijri() ? m.add(value, 'iDate') : m.add(value, 'date');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Increments the month by the passed value.
|
|
47
|
+
*
|
|
48
|
+
* @param date
|
|
49
|
+
* @param value
|
|
50
|
+
*
|
|
51
|
+
* @returns {*}
|
|
52
|
+
*/
|
|
53
|
+
addMonth(date: Date, value: number) {
|
|
54
|
+
const m = this.moment(date);
|
|
55
|
+
return this.isHijri() ? m.add(value, 'iMonth') : m.add(value, 'month');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Increments the year by the passed value.
|
|
60
|
+
*
|
|
61
|
+
* @param date
|
|
62
|
+
* @param value
|
|
63
|
+
*
|
|
64
|
+
* @returns {*}
|
|
65
|
+
*/
|
|
66
|
+
addYear(date: Date, value: number) {
|
|
67
|
+
const m = this.moment(date);
|
|
68
|
+
return this.isHijri() ? m.add(value, 'iYear') : m.add(value, 'year');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Converts the passed year, month, and date to a moment Date object.
|
|
73
|
+
*
|
|
74
|
+
* @param year
|
|
75
|
+
* @param month
|
|
76
|
+
* @param date
|
|
77
|
+
*
|
|
78
|
+
* @returns {moment.Moment}
|
|
79
|
+
*/
|
|
80
|
+
convertToDate({ year, month, date }: { year: number, month: number, date: number }) {
|
|
81
|
+
let m = this.moment().hours(0).minutes(0).seconds(0);
|
|
82
|
+
|
|
83
|
+
if (this.isHijri()) {
|
|
84
|
+
m = m
|
|
85
|
+
.iYear(year || this.getDefaultYear())
|
|
86
|
+
.iMonth(month || this.getDefaultMonth())
|
|
87
|
+
.iDate(date || this.getDefaultDate());
|
|
88
|
+
} else {
|
|
89
|
+
m = m
|
|
90
|
+
.year(year || this.getDefaultYear())
|
|
91
|
+
.month(month || this.getDefaultMonth())
|
|
92
|
+
.date(date || this.getDefaultDate());
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return m;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Returns the days in the month for the passed year/month.
|
|
100
|
+
*
|
|
101
|
+
* @param year
|
|
102
|
+
* @param month
|
|
103
|
+
*
|
|
104
|
+
* @returns {number}
|
|
105
|
+
*/
|
|
106
|
+
daysInMonth(year: number, month: number) {
|
|
107
|
+
const y = year || this.getDefaultYear();
|
|
108
|
+
const m = month || this.getDefaultMonth();
|
|
109
|
+
|
|
110
|
+
const date = this.convertToDate({ year: y, month: m, date: this.getDefaultDate() });
|
|
111
|
+
return (this.isHijri() ? date.iDaysInMonth() : date.daysInMonth()) || MAX_DAYS_IN_MONTH;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Formats the passed date.
|
|
116
|
+
*
|
|
117
|
+
* @param date
|
|
118
|
+
* @param format
|
|
119
|
+
*
|
|
120
|
+
* @returns {*}
|
|
121
|
+
*/
|
|
122
|
+
format(date: moment, format: number = Calendar.DateFormats.gregorian) {
|
|
123
|
+
return this.moment(date).format(Calendar.DateFormats[this.name][format]);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Returns the default date for the current calendar.
|
|
128
|
+
*
|
|
129
|
+
* @returns {*}
|
|
130
|
+
*/
|
|
131
|
+
getDefaultDate() {
|
|
132
|
+
return Calendar.Defaults[this.name].date;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Returns the default month for the current calendar.
|
|
137
|
+
*
|
|
138
|
+
* @returns {*}
|
|
139
|
+
*/
|
|
140
|
+
getDefaultMonth() {
|
|
141
|
+
return Calendar.Defaults[this.name].month;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Returns the default year for the current calendar.
|
|
146
|
+
*
|
|
147
|
+
* @returns {number|*|"numeric"|"2-digit"|string|((y: number) => moment.Moment)|(() => number)|moment.numberlike}
|
|
148
|
+
*/
|
|
149
|
+
getDefaultYear() {
|
|
150
|
+
return Calendar.Defaults[this.name].year;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Returns true if the current calendar is Hijri.
|
|
155
|
+
*
|
|
156
|
+
* @returns {boolean}
|
|
157
|
+
*/
|
|
158
|
+
isHijri() {
|
|
159
|
+
return this.name === Calendar.Calendars.hijri;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Returns the list of months for the current calendar.
|
|
164
|
+
*
|
|
165
|
+
* @returns {*}
|
|
166
|
+
*/
|
|
167
|
+
listMonths() {
|
|
168
|
+
const localeData = this.moment().localeData();
|
|
169
|
+
return this.isHijri() ? localeData._iMonths : localeData.months();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Wraps the passed date/string in a moment object.
|
|
174
|
+
*
|
|
175
|
+
* @param date
|
|
176
|
+
*/
|
|
177
|
+
moment(date: ?any = null) {
|
|
178
|
+
const m = date ? moment(date) : moment();
|
|
179
|
+
m.locale(this.locale);
|
|
180
|
+
return m;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Parses the passed date into year, month, and date components.
|
|
185
|
+
*
|
|
186
|
+
* @param date
|
|
187
|
+
*
|
|
188
|
+
* @returns {{date: (*), month: (*), year: (*)}}
|
|
189
|
+
*/
|
|
190
|
+
parseDate(date: Date | string) {
|
|
191
|
+
const m = this.moment(date);
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
year: this.isHijri() ? m.iYear() : m.year(),
|
|
195
|
+
month: this.isHijri() ? m.iMonth() : m.month(),
|
|
196
|
+
date: this.isHijri() ? m.iDate() : m.date()
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
Calendar.Calendars = {
|
|
202
|
+
gregorian: 'gregorian',
|
|
203
|
+
hijri: 'hijri'
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
Calendar.DateFormats = {
|
|
207
|
+
[Calendar.Calendars.gregorian]: {
|
|
208
|
+
'0': 'YYYY',
|
|
209
|
+
'1': 'MMMM YYYY',
|
|
210
|
+
'2': 'L'
|
|
211
|
+
},
|
|
212
|
+
[Calendar.Calendars.hijri]: {
|
|
213
|
+
'0': 'iYYYY',
|
|
214
|
+
'1': 'iMMMM iYYYY',
|
|
215
|
+
'2': 'iM/iD/iYYYY'
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
Calendar.Defaults = {
|
|
220
|
+
[Calendar.Calendars.gregorian]: {
|
|
221
|
+
year: 0,
|
|
222
|
+
month: 0,
|
|
223
|
+
date: 1
|
|
224
|
+
},
|
|
225
|
+
[Calendar.Calendars.hijri]: {
|
|
226
|
+
year: 1410,
|
|
227
|
+
month: 0,
|
|
228
|
+
date: 1
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
export default Calendar;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React, { type ComponentType } from 'react';
|
|
4
|
+
import { DndProvider } from 'react-dnd';
|
|
5
|
+
import { HTML5Backend, type BackendFactory } from 'react-dnd-html5-backend';
|
|
6
|
+
|
|
7
|
+
const useDragDrop = (WrappedComponent: ComponentType<any>, backend: BackendFactory = HTML5Backend) => (
|
|
8
|
+
() => (
|
|
9
|
+
<DndProvider
|
|
10
|
+
backend={backend}
|
|
11
|
+
>
|
|
12
|
+
<WrappedComponent />
|
|
13
|
+
</DndProvider>
|
|
14
|
+
)
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
export default useDragDrop;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Returns the subset of children matching the passed component type. This function is useful for designing components
|
|
7
|
+
* using a sub-component type syntax:
|
|
8
|
+
*
|
|
9
|
+
* <MyComponent ...>
|
|
10
|
+
* <MyComponent.Subcomponent ... />
|
|
11
|
+
* <MyComponent.AnotherSubcomponent ... />
|
|
12
|
+
* </MyComponent>
|
|
13
|
+
*
|
|
14
|
+
* @param children
|
|
15
|
+
* @param component
|
|
16
|
+
*
|
|
17
|
+
* @returns {[]}
|
|
18
|
+
*/
|
|
19
|
+
const findByType = (children: any, component: any) => {
|
|
20
|
+
const components = [];
|
|
21
|
+
|
|
22
|
+
const type = [component.displayName || component.name];
|
|
23
|
+
|
|
24
|
+
React.Children.forEach(children, (child) => {
|
|
25
|
+
const childType = child && child.type && (child.type.displayName || child.type.name);
|
|
26
|
+
if (type.includes(childType)) {
|
|
27
|
+
components.push(child);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
return components;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export default {
|
|
35
|
+
findByType
|
|
36
|
+
};
|
package/src/utils/Map.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns the numeric latitude and longitude for the passed coordinates.
|
|
5
|
+
*
|
|
6
|
+
* @param coords
|
|
7
|
+
*
|
|
8
|
+
* @returns {*}
|
|
9
|
+
*/
|
|
10
|
+
const getPosition = (coords: ?{ lat: any, lng: any }) => {
|
|
11
|
+
let position;
|
|
12
|
+
|
|
13
|
+
if (coords) {
|
|
14
|
+
const lat = Number.parseFloat(coords.lat);
|
|
15
|
+
const lng = Number.parseFloat(coords.lng);
|
|
16
|
+
|
|
17
|
+
if (!Number.isNaN(lat) && !Number.isNaN(lng)) {
|
|
18
|
+
position = { lat, lng };
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return position;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default {
|
|
26
|
+
getPosition
|
|
27
|
+
};
|