ngx-edu-sharing-ui 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/.browserslistrc +16 -0
  2. package/.eslintrc.json +44 -0
  3. package/README.md +40 -0
  4. package/assets/scss/mixins.scss +95 -0
  5. package/assets/scss/variables.scss +33 -0
  6. package/karma.conf.js +42 -0
  7. package/ng-package.json +10 -0
  8. package/package.json +19 -0
  9. package/src/lib/actionbar/actionbar.component.html +59 -0
  10. package/src/lib/actionbar/actionbar.component.scss +123 -0
  11. package/src/lib/actionbar/actionbar.component.ts +174 -0
  12. package/src/lib/common/edu-sharing-ui-common.module.ts +80 -0
  13. package/src/lib/directives/border-box-observer.directive.ts +75 -0
  14. package/src/lib/directives/check-text-overflow.directive.ts +61 -0
  15. package/src/lib/directives/drag-nodes/drag-nodes.ts +32 -0
  16. package/src/lib/directives/drag-nodes/nodes-drag-source.directive.ts +79 -0
  17. package/src/lib/directives/drag-nodes/nodes-drag.directive.ts +43 -0
  18. package/src/lib/directives/drag-nodes/nodes-drop-target.directive.ts +116 -0
  19. package/src/lib/directives/focus-state.directive.ts +34 -0
  20. package/src/lib/directives/icon.directive.ts +142 -0
  21. package/src/lib/directives/nodes-drop-target-legacy.directive.ts +155 -0
  22. package/src/lib/dropdown/dropdown.component.html +32 -0
  23. package/src/lib/dropdown/dropdown.component.scss +67 -0
  24. package/src/lib/dropdown/dropdown.component.ts +71 -0
  25. package/src/lib/edu-sharing-ui-configuration.ts +47 -0
  26. package/src/lib/edu-sharing-ui.module.ts +49 -0
  27. package/src/lib/list-items/available-widgets.ts +30 -0
  28. package/src/lib/list-items/format-duration.pipe.ts +17 -0
  29. package/src/lib/list-items/list-base/list-base.component.html +52 -0
  30. package/src/lib/list-items/list-base/list-base.component.ts +44 -0
  31. package/src/lib/list-items/list-collection-info/list-collection-info.component.html +48 -0
  32. package/src/lib/list-items/list-collection-info/list-collection-info.component.scss +8 -0
  33. package/src/lib/list-items/list-collection-info/list-collection-info.component.ts +24 -0
  34. package/src/lib/list-items/list-counts/list-counts.component.html +1 -0
  35. package/src/lib/list-items/list-counts/list-counts.component.scss +3 -0
  36. package/src/lib/list-items/list-counts/list-counts.component.ts +59 -0
  37. package/src/lib/list-items/list-items.module.ts +33 -0
  38. package/src/lib/list-items/list-node-license/list-node-license.component.html +8 -0
  39. package/src/lib/list-items/list-node-license/list-node-license.component.ts +47 -0
  40. package/src/lib/list-items/list-node-replication-source/list-node-replication-source.component.html +11 -0
  41. package/src/lib/list-items/list-node-replication-source/list-node-replication-source.component.ts +60 -0
  42. package/src/lib/list-items/list-node-workflow/list-node-workflow.component.html +3 -0
  43. package/src/lib/list-items/list-node-workflow/list-node-workflow.component.ts +21 -0
  44. package/src/lib/list-items/list-text/list-text.component.html +176 -0
  45. package/src/lib/list-items/list-text/list-text.component.scss +3 -0
  46. package/src/lib/list-items/list-text/list-text.component.ts +107 -0
  47. package/src/lib/list-items/list-widget.ts +52 -0
  48. package/src/lib/list-items/node-row/node-row.component.html +31 -0
  49. package/src/lib/list-items/node-row/node-row.component.scss +50 -0
  50. package/src/lib/list-items/node-row/node-row.component.ts +16 -0
  51. package/src/lib/list-items/node-source.pipe.ts +48 -0
  52. package/src/lib/node-entries/combined-data-source.ts +51 -0
  53. package/src/lib/node-entries/custom-templates-data-source.ts +6 -0
  54. package/src/lib/node-entries/drag-preview/drag-preview.component.html +6 -0
  55. package/src/lib/node-entries/drag-preview/drag-preview.component.scss +35 -0
  56. package/src/lib/node-entries/drag-preview/drag-preview.component.ts +15 -0
  57. package/src/lib/node-entries/entries-model.ts +120 -0
  58. package/src/lib/node-entries/items-cap.ts +54 -0
  59. package/src/lib/node-entries/list-item-label.pipe.ts +28 -0
  60. package/src/lib/node-entries/mixins.scss +23 -0
  61. package/src/lib/node-entries/node-cache.spec.ts +199 -0
  62. package/src/lib/node-entries/node-cache.ts +81 -0
  63. package/src/lib/node-entries/node-data-source-remote.ts +33 -0
  64. package/src/lib/node-entries/node-data-source.ts +148 -0
  65. package/src/lib/node-entries/node-entries-card/node-entries-card.component.html +167 -0
  66. package/src/lib/node-entries/node-entries-card/node-entries-card.component.scss +28 -0
  67. package/src/lib/node-entries/node-entries-card/node-entries-card.component.ts +132 -0
  68. package/src/lib/node-entries/node-entries-card/node-entries-card.main.scss +261 -0
  69. package/src/lib/node-entries/node-entries-card-grid/node-entries-card-grid.component.html +205 -0
  70. package/src/lib/node-entries/node-entries-card-grid/node-entries-card-grid.component.scss +181 -0
  71. package/src/lib/node-entries/node-entries-card-grid/node-entries-card-grid.component.ts +361 -0
  72. package/src/lib/node-entries/node-entries-card-small/node-entries-card-small.component.html +100 -0
  73. package/src/lib/node-entries/node-entries-card-small/node-entries-card-small.component.scss +46 -0
  74. package/src/lib/node-entries/node-entries-card-small/node-entries-card-small.component.ts +40 -0
  75. package/src/lib/node-entries/node-entries-global-options/node-entries-global-options.component.html +23 -0
  76. package/src/lib/node-entries/node-entries-global-options/node-entries-global-options.component.scss +58 -0
  77. package/src/lib/node-entries/node-entries-global-options/node-entries-global-options.component.ts +16 -0
  78. package/src/lib/node-entries/node-entries-global.service.ts +79 -0
  79. package/src/lib/node-entries/node-entries-table/column-chooser/column-chooser.component.html +25 -0
  80. package/src/lib/node-entries/node-entries-table/column-chooser/column-chooser.component.scss +32 -0
  81. package/src/lib/node-entries/node-entries-table/column-chooser/column-chooser.component.ts +31 -0
  82. package/src/lib/node-entries/node-entries-table/node-entries-table.component.html +270 -0
  83. package/src/lib/node-entries/node-entries-table/node-entries-table.component.scss +169 -0
  84. package/src/lib/node-entries/node-entries-table/node-entries-table.component.ts +333 -0
  85. package/src/lib/node-entries/node-entries-templates.service.ts +31 -0
  86. package/src/lib/node-entries/node-entries-wrapper.component.ts +363 -0
  87. package/src/lib/node-entries/node-entries.component.html +33 -0
  88. package/src/lib/node-entries/node-entries.component.scss +13 -0
  89. package/src/lib/node-entries/node-entries.component.ts +151 -0
  90. package/src/lib/node-entries/node-entries.module.ts +93 -0
  91. package/src/lib/node-entries/node-rating/node-rating.component.html +53 -0
  92. package/src/lib/node-entries/node-rating/node-rating.component.scss +31 -0
  93. package/src/lib/node-entries/node-rating/node-rating.component.ts +105 -0
  94. package/src/lib/node-entries/node-stats-badges/node-stats-badges.component.html +39 -0
  95. package/src/lib/node-entries/node-stats-badges/node-stats-badges.component.scss +44 -0
  96. package/src/lib/node-entries/node-stats-badges/node-stats-badges.component.ts +43 -0
  97. package/src/lib/node-entries/node-type-badge/node-type-badge.component.html +31 -0
  98. package/src/lib/node-entries/node-type-badge/node-type-badge.component.scss +5 -0
  99. package/src/lib/node-entries/node-type-badge/node-type-badge.component.ts +36 -0
  100. package/src/lib/node-entries/option-button/option-button.component.ts +42 -0
  101. package/src/lib/node-entries/preview-image/preview-image.component.html +19 -0
  102. package/src/lib/node-entries/preview-image/preview-image.component.scss +31 -0
  103. package/src/lib/node-entries/preview-image/preview-image.component.ts +47 -0
  104. package/src/lib/node-entries/sort-select-panel/sort-select-panel.component.html +27 -0
  105. package/src/lib/node-entries/sort-select-panel/sort-select-panel.component.scss +9 -0
  106. package/src/lib/node-entries/sort-select-panel/sort-select-panel.component.ts +26 -0
  107. package/src/lib/node-url/node-url.component.html +66 -0
  108. package/src/lib/node-url/node-url.component.scss +32 -0
  109. package/src/lib/node-url/node-url.component.ts +136 -0
  110. package/src/lib/pipes/file-size.pipe.ts +24 -0
  111. package/src/lib/pipes/format-date.pipe.ts +39 -0
  112. package/src/lib/pipes/node-icon.pipe.ts +11 -0
  113. package/src/lib/pipes/node-image-size.pipe.ts +18 -0
  114. package/src/lib/pipes/node-image.pipe.ts +71 -0
  115. package/src/lib/pipes/node-person-name.pipe.ts +41 -0
  116. package/src/lib/pipes/node-title.pipe.ts +12 -0
  117. package/src/lib/pipes/option-tooltip.pipe.ts +32 -0
  118. package/src/lib/pipes/replace-chars.pipe.ts +21 -0
  119. package/src/lib/pipes/vcard-name.pipe.ts +11 -0
  120. package/src/lib/services/abstract/app.service.ts +4 -0
  121. package/src/lib/services/abstract/keyboard-shortcuts.service.ts +10 -0
  122. package/src/lib/services/abstract/options-helper.service.ts +29 -0
  123. package/src/lib/services/abstract/toast.service.ts +5 -0
  124. package/src/lib/services/accessibility.service.ts +101 -0
  125. package/src/lib/services/local-events.service.ts +29 -0
  126. package/src/lib/services/node-entries.service.ts +172 -0
  127. package/src/lib/services/node-helper.service.ts +239 -0
  128. package/src/lib/services/nodes-drag-drop.service.ts +165 -0
  129. package/src/lib/services/options-helper-data.service.ts +186 -0
  130. package/src/lib/services/repo-url.service.ts +46 -0
  131. package/src/lib/services/temporary-storage.service.ts +58 -0
  132. package/src/lib/services/ui.service.ts +182 -0
  133. package/src/lib/sort-dropdown/sort-dropdown.component.html +22 -0
  134. package/src/lib/sort-dropdown/sort-dropdown.component.scss +47 -0
  135. package/src/lib/sort-dropdown/sort-dropdown.component.ts +42 -0
  136. package/src/lib/spinner/spinner.component.html +14 -0
  137. package/src/lib/spinner/spinner.component.scss +141 -0
  138. package/src/lib/spinner/spinner.component.ts +12 -0
  139. package/src/lib/translations/README.md +44 -0
  140. package/src/lib/translations/fallback-translation-handler.ts +7 -0
  141. package/src/lib/translations/languages.ts +6 -0
  142. package/src/lib/translations/translation-loader.spec.ts +352 -0
  143. package/src/lib/translations/translation-loader.ts +189 -0
  144. package/src/lib/translations/translation-source.ts +9 -0
  145. package/src/lib/translations/translations.module.ts +49 -0
  146. package/src/lib/translations/translations.service.spec.ts +152 -0
  147. package/src/lib/translations/translations.service.ts +188 -0
  148. package/src/lib/types/accessibillity.ts +15 -0
  149. package/src/lib/types/api-models.ts +4 -0
  150. package/src/lib/types/drag-drop.ts +22 -0
  151. package/src/lib/types/keyboard-shortcuts.ts +29 -0
  152. package/src/lib/types/list-item.ts +67 -0
  153. package/src/lib/types/option-item.ts +247 -0
  154. package/src/lib/types/workflow.ts +35 -0
  155. package/src/lib/util/DateHelper.spec.ts +112 -0
  156. package/src/lib/util/DateHelper.ts +197 -0
  157. package/src/lib/util/VCard.ts +277 -0
  158. package/src/lib/util/color-helper.ts +125 -0
  159. package/src/lib/util/duration-helper.spec.ts +35 -0
  160. package/src/lib/util/duration-helper.ts +98 -0
  161. package/src/lib/util/functions.ts +15 -0
  162. package/src/lib/util/helper.ts +60 -0
  163. package/src/lib/util/isNumeric.ts +13 -0
  164. package/src/lib/util/rest-helper.ts +28 -0
  165. package/src/lib/util/ui-animation.ts +154 -0
  166. package/src/lib/util/ui-constants.ts +20 -0
  167. package/src/module.ts +76 -0
  168. package/src/test.ts +28 -0
  169. package/tsconfig.lib.json +15 -0
  170. package/tsconfig.lib.prod.json +10 -0
  171. package/tsconfig.spec.json +17 -0
@@ -0,0 +1,67 @@
1
+ import { Sort, SortDirection } from '@angular/material/sort';
2
+ import { Observable } from 'rxjs';
3
+
4
+ export type ListItemType = 'NODE' | 'NODE_PROPOSAL' | 'COLLECTION' | 'ORG' | 'GROUP' | 'USER';
5
+
6
+ /**
7
+ * A list item info, which is basically a column
8
+ * Example:
9
+ this.columns.push(new ListItem(RestConstants.CM_NAME));
10
+ this.columns.push(new ListItem(RestConstants.CM_ARCHIVED_DATE));
11
+ */
12
+ export class ListItem {
13
+ /**
14
+ * Should this item be shown by default
15
+ * @type {boolean}
16
+ */
17
+ public visible = true;
18
+
19
+ /**
20
+ * Label to display, if set, should be preferred instead of automatic i18n
21
+ */
22
+ public label: string;
23
+
24
+ /**
25
+ * custom format string for date fields, may be null
26
+ */
27
+ public format: string;
28
+ constructor(
29
+ public type: ListItemType,
30
+ public name: string,
31
+ public config = {
32
+ showLabel: false,
33
+ },
34
+ ) {}
35
+
36
+ static getCollectionDefaults() {
37
+ let columns = [];
38
+ columns.push(new ListItem('COLLECTION', 'title'));
39
+ columns.push(new ListItem('COLLECTION', 'info'));
40
+ columns.push(new ListItem('COLLECTION', 'scope'));
41
+ return columns;
42
+ }
43
+ }
44
+ export class ListItemSort extends ListItem {
45
+ constructor(
46
+ public type: ListItemType,
47
+ public name: string,
48
+ public mode: 'ascending' | 'descending' | null = null,
49
+ public config = {
50
+ showLabel: false,
51
+ },
52
+ ) {
53
+ super(type, name, config);
54
+ }
55
+ }
56
+ export class SortEvent extends ListItemSort {
57
+ ascending: boolean;
58
+ }
59
+
60
+ /**
61
+ * UI element that allows the user to choose sorting.
62
+ */
63
+ export interface SortPanel {
64
+ active: string;
65
+ direction: SortDirection;
66
+ readonly sortChange: Observable<Sort>;
67
+ }
@@ -0,0 +1,247 @@
1
+ /**
2
+ * A option from the actionbar+dropdown menu
3
+ * Example:
4
+ this.options.push(new OptionItem("RESTORE_SINGLE","undo", (node) => this.restoreSingle(node)));
5
+ this.options.push(new OptionItem("DELETE_SINGLE","archiveDelete", (node) => this.deleteSingle(node)));
6
+
7
+ */
8
+ import { KeyboardShortcutCondition } from '../types/keyboard-shortcuts';
9
+
10
+ export enum NodesRightMode {
11
+ Local,
12
+ Original,
13
+ Both,
14
+ }
15
+ export class OptionItem {
16
+ /**
17
+ * If true, this option will be shown all the time in the node table
18
+ * @type {boolean}
19
+ */
20
+ public showAlways = false;
21
+ /**
22
+ * If true, this option will be shown as an action (if room). If none of the items has showAsAction set, the first items will always be shown as action
23
+ * @type {boolean}
24
+ */
25
+ public showAsAction = false;
26
+ /**
27
+ * If true, this option will be shown as a toggle on the right side (provide iconToggle as a toggle icon)
28
+ * @type {boolean}
29
+ */
30
+ public isToggle = false;
31
+ /**
32
+ * If true, shows a line at the top.
33
+ *
34
+ * This feature is usually handled now by associating an entry to a `group`
35
+ * now. However `isSeparate` is kept as fallback for now.
36
+ */
37
+ public isSeparate = false;
38
+ /**
39
+ * The item will be indicated with an accent color in the menu.
40
+ *
41
+ * Used by the dropdown variant of the main menu to indicate the currently
42
+ * active scope.
43
+ */
44
+ public isSelected = false;
45
+ /**
46
+ * If true, only displayed on a mobile device (based on the navigator agent)
47
+ * @type {boolean}
48
+ */
49
+ public onlyMobile = false;
50
+ /**
51
+ * If true, only displayed on a desktop device (based on the navigator agent)
52
+ * @type {boolean}
53
+ */
54
+ public onlyDesktop = false;
55
+ /**
56
+ * You can set a media-query similar to CSS, see the MEDIA_QUERY constants in ui-constants
57
+ * Use in combination with mediaQueryValue
58
+ * @type {boolean}
59
+ */
60
+ public mediaQueryType: string;
61
+ /**
62
+ * The value for the defined media query
63
+ */
64
+ public mediaQueryValue: number;
65
+
66
+ /**
67
+ * Set to false if the action should be shown, but should not be clickable
68
+ * @type {boolean}
69
+ */
70
+ public isEnabled = true;
71
+
72
+ /**
73
+ * Whether the option should be manually marked as primary action when always visible on an
74
+ * `actionbar`.
75
+ */
76
+ public isPrimary: boolean;
77
+
78
+ /**
79
+ * A function called with the node as param which should return true or false if the option should be shown for this node
80
+ * Is handled by optionsHelper and may not be used otherwise
81
+ * Please use @customShowCallback instead
82
+ */
83
+ public showCallback: (node?: Node | any) => boolean;
84
+ /**
85
+ * A function called with the node as parm which should return true or false if the option should be shown for this node
86
+ * Will be called by the optionsHelper
87
+ */
88
+ public customShowCallback: (nodes?: Node[] | any[]) => boolean;
89
+ /**
90
+ * A function called with the node as param which should return true or false if the option should be enabled or not
91
+ * Is handled by optionsHelper and may not be used otherwise
92
+ * Please use @customEnabledCallback instead
93
+ */
94
+ public enabledCallback: (node?: Node | any) => boolean;
95
+ /**
96
+ * A function called with the node as param which should return true or false if the option should be enabled or not
97
+ * Will be called by the optionsHelper
98
+ */
99
+ public customEnabledCallback: (nodes?: Node[] | any[]) => boolean;
100
+
101
+ /**
102
+ * Optional: A callback that is called when the user clicks on the option when it's currently disabled (greyed out)
103
+ */
104
+ public disabledCallback: (node?: Node | any) => void;
105
+ /**
106
+ * Show the given name (if false, only icon will show)
107
+ */
108
+ public showName = true;
109
+
110
+ /**
111
+ * element with 0 has highest priority in it's group, higher values mean lower priority
112
+ */
113
+ public priority: number;
114
+ /**
115
+ * the group this option belongs to
116
+ */
117
+ public group: OptionGroup;
118
+
119
+ public keyboardShortcut: KeyboardShortcutCondition;
120
+
121
+ /**
122
+ * Or concat of supported element types for the action
123
+ */
124
+ public elementType = [ElementType.Node];
125
+ public permissions: string[];
126
+ public constrains: Constrain[];
127
+ public permissionsMode = HideMode.Disable;
128
+ public permissionsRightMode = NodesRightMode.Local;
129
+ public toolpermissions: string[];
130
+ public toolpermissionsMode = HideMode.Disable;
131
+ public scopes: Scope[];
132
+
133
+ /**
134
+ *
135
+ * @param name the option name, which is used for the translation
136
+ * @param icon A material icon name
137
+ * @param callback A function callback when this option is chosen. Will get the current node
138
+ * passed as an argument. If available, the relevant nodes are passed as second argument,
139
+ * i.e., the selection, if any, or the current node as single-item array otherwise.
140
+ */
141
+ constructor(
142
+ public name: string,
143
+ public icon: string,
144
+ // TODO: Maybe switch to only providing the second parameter.
145
+ public callback: (object?: Node | any, objects?: (Node | any)[]) => void,
146
+ ) {}
147
+ }
148
+ export class CustomOptions {
149
+ /**
150
+ * If true, all existing or available options for the object stay
151
+ * If false, no options will be set, only the options in "addOptions" are used
152
+ */
153
+ public useDefaultOptions? = true;
154
+ /**
155
+ * List of ids of options to explicitly support
156
+ */
157
+ public supportedOptions?: string[];
158
+ /**
159
+ * List of ids of options to explicitly remove
160
+ * Only supported if supportedOptions is empty
161
+ */
162
+ public removeOptions?: string[];
163
+ /**
164
+ * Options to add/insert into the menu
165
+ */
166
+ public addOptions?: OptionItem[];
167
+ }
168
+ export enum HideMode {
169
+ Disable,
170
+ Hide,
171
+ }
172
+ export enum Scope {
173
+ Render = 'Render',
174
+ Search = 'Search',
175
+ SearchCollections = 'SearchCollections',
176
+ SavedSearches = 'SavedSearches',
177
+ CollectionsReferences = 'CollectionsReferences',
178
+ CollectionsProposals = 'CollectionsProposals',
179
+ CollectionsCollection = 'CollectionsCollection',
180
+ WorkspaceList = 'WorkspaceList',
181
+ WorkspaceTree = 'WorkspaceTree',
182
+ Sharing = 'Sharing',
183
+ Oer = 'Oer',
184
+ UserManagement = 'UserManagement',
185
+ Stream = 'Stream',
186
+ CreateMenu = 'CreateMenu',
187
+
188
+ MediacenterNodesList = 'MediacenterNodesList',
189
+ Admin = 'Admin', // Admin Tools / Debugging
190
+ }
191
+ export enum ElementType {
192
+ Node,
193
+ NodeChild, // Child object
194
+ MapRef, // Map ref (link to another map)
195
+ NodePublishedCopy,
196
+ NodeBlockedImport, // node with property ccm:importblocked == true
197
+ NodeProposal, // node proposal for a collection
198
+ Person,
199
+ Group,
200
+ SavedSearch,
201
+ Unknown,
202
+ }
203
+ export class OptionGroup {
204
+ /**
205
+ * @param id The group identifier. Used to seperate elements based on the group
206
+ * @param priority Group with 0 has highest priority, higher values mean lower priority
207
+ */
208
+ constructor(public id: string, public priority: number) {}
209
+ }
210
+ export class DefaultGroups {
211
+ static Primary = new OptionGroup('Primary', 10);
212
+ static Create = new OptionGroup('Create', 15);
213
+ static View = new OptionGroup('View', 20);
214
+ static CreateConnector = new OptionGroup('CreateConnector', 25);
215
+ static CreateLtiTools = new OptionGroup('CreateLtiTools', 28);
216
+ static Reuse = new OptionGroup('Reuse', 30);
217
+ static Edit = new OptionGroup('Edit', 40);
218
+ static FileOperations = new OptionGroup('FileOperations', 50);
219
+ static Delete = new OptionGroup('Delete', 60);
220
+ static Toggles = new OptionGroup('Toggles', 70);
221
+ }
222
+ export enum Constrain {
223
+ CollectionReference, // option is only visible for collection references
224
+ NoCollectionReference, // option is only visible for non-collection references
225
+ Directory, // only visible for directories (ccm:map)
226
+ Collections, // only visible for collections
227
+ Files, // only visible for files (ccm:io)
228
+ FilesAndDirectories, // only visible for files and directories (ccm:io / ccm:map) - no collections!
229
+ Admin, // only visible if user is admin or esDebug is enabled on window component
230
+ AdminOrDebug, // only visible if user is admin or esDebug is enabled on window component
231
+ NoBulk, // No support for bulk (multiple objects)
232
+ NoSelection, // Only visible when currently no element is selected
233
+ ClipboardContent, // Only visible when the clipboard has content
234
+ AddObjects, // Only visible when it is possible to add objects into the current list
235
+ HomeRepository, // Only visible when the nodes are from the local (home) repository
236
+ User, // Only visible when a user is present and logged in
237
+ NoScope, // Only visible when no current scope (i.e "safe" scope) is set
238
+ ReurlMode, // Only visible when a reurl is present (called to pick object from lms)
239
+ LTIMode, // Only visible when a lti session is present (called to pick object from lti platform)
240
+ }
241
+
242
+ export enum Target {
243
+ List, // Target is the ListTableComponent
244
+ ListDropdown,
245
+ Actionbar,
246
+ CreateMenu,
247
+ }
@@ -0,0 +1,35 @@
1
+ export interface WorkflowDefinition {
2
+ id: string;
3
+ color: string;
4
+ hasReceiver: boolean;
5
+ next: string[];
6
+ }
7
+
8
+ export const WORKFLOW_STATUS_UNCHECKED: WorkflowDefinition = {
9
+ id: '100_unchecked',
10
+ color: '#539DD5',
11
+ hasReceiver: true,
12
+ next: null,
13
+ };
14
+ export const WORKFLOW_STATUS_TO_CHECK: WorkflowDefinition = {
15
+ id: '200_tocheck',
16
+ color: '#3CB0B0',
17
+ hasReceiver: true,
18
+ next: null,
19
+ };
20
+ export const WORKFLOW_STATUS_HASFLAWS: WorkflowDefinition = {
21
+ id: '300_hasflaws',
22
+ color: '#D58553',
23
+ hasReceiver: true,
24
+ next: null,
25
+ };
26
+ export const WORKFLOW_STATUS_CHECKED: WorkflowDefinition = {
27
+ id: '400_checked',
28
+ color: '#42A053',
29
+ hasReceiver: false,
30
+ next: null,
31
+ };
32
+ export type WorkflowDefinitionStatus = {
33
+ current: WorkflowDefinition;
34
+ initial: WorkflowDefinition;
35
+ };
@@ -0,0 +1,112 @@
1
+ import { DateHelper, FormatOptions, RelativeMode } from './DateHelper';
2
+ import { TranslateService } from '@ngx-translate/core/lib/translate.service';
3
+
4
+ const translateServiceMock = {
5
+ instant: (key: string, values?: any) => key + JSON.stringify(values),
6
+ } as TranslateService;
7
+ describe('testing relative dates', () => {
8
+ const date_now = new Date(new Date().getTime());
9
+ const date_10_mins_before = new Date(new Date().getTime() - 1000 - 10 * 60 * 1000);
10
+ const date_4_hours_before = new Date(new Date().getTime() - 1000 - 4 * 3600 * 1000);
11
+ const date_1_day_before = new Date(new Date().getTime() - 1000 - 24 * 3600 * 1000);
12
+ const date_2_days_before = new Date(new Date().getTime() - 1000 - 2 * 24 * 3600 * 1000);
13
+ const date_7_days_before = new Date(new Date().getTime() - 1000 - 7 * 24 * 3600 * 1000);
14
+ const date_2_months_before = new Date();
15
+ date_2_months_before.setMonth(date_2_months_before.getMonth() - 2);
16
+ const date_1_year_before = new Date();
17
+ date_1_year_before.setFullYear(date_1_year_before.getFullYear() - 1);
18
+ for (const mode of [
19
+ RelativeMode.short,
20
+ RelativeMode.medium,
21
+ RelativeMode.large,
22
+ RelativeMode.all,
23
+ ]) {
24
+ it('testing relative mode ' + mode, () => {
25
+ const options: FormatOptions = {
26
+ relativeLabels: mode as any,
27
+ showAlwaysTime: false,
28
+ };
29
+ expect(DateHelper.formatDate(translateServiceMock, date_now, options)).toContain(
30
+ 'JUST_NOW',
31
+ );
32
+ expect(
33
+ DateHelper.formatDate(translateServiceMock, date_4_hours_before, options),
34
+ ).toContain('HOURS_AGO');
35
+ expect(
36
+ DateHelper.formatDate(translateServiceMock, date_4_hours_before, options),
37
+ ).toContain('4');
38
+ expect(
39
+ DateHelper.formatDate(translateServiceMock, date_10_mins_before, options),
40
+ ).toContain('MINUTES_AGO');
41
+ expect(
42
+ DateHelper.formatDate(translateServiceMock, date_10_mins_before, options),
43
+ ).toContain('10');
44
+ if (mode === RelativeMode.short) {
45
+ expect(
46
+ DateHelper.formatDate(translateServiceMock, date_1_day_before, options),
47
+ ).not.toContain('YESTERDAY');
48
+ expect(
49
+ DateHelper.formatDate(translateServiceMock, date_2_days_before, options),
50
+ ).not.toBe('DAYS_AGO');
51
+ expect(
52
+ DateHelper.formatDate(translateServiceMock, date_7_days_before, options),
53
+ ).not.toBe('DAYS_AGO');
54
+ } else {
55
+ expect(
56
+ DateHelper.formatDate(translateServiceMock, date_1_day_before, options),
57
+ ).toContain('YESTERDAY');
58
+ expect(
59
+ DateHelper.formatDate(translateServiceMock, date_2_days_before, options),
60
+ ).toContain('DAYS_AGO');
61
+ expect(
62
+ DateHelper.formatDate(translateServiceMock, date_2_days_before, options),
63
+ ).toContain('2');
64
+ if (mode === RelativeMode.medium) {
65
+ expect(
66
+ DateHelper.formatDate(translateServiceMock, date_7_days_before, options),
67
+ ).not.toContain('DAYS_AGO');
68
+ expect(
69
+ DateHelper.formatDate(translateServiceMock, date_2_months_before, options),
70
+ ).not.toContain('MONTHS_AGO');
71
+ } else {
72
+ expect(
73
+ DateHelper.formatDate(translateServiceMock, date_7_days_before, options),
74
+ ).toContain('DAYS_AGO');
75
+ expect(
76
+ DateHelper.formatDate(translateServiceMock, date_7_days_before, options),
77
+ ).toContain('7');
78
+ expect(
79
+ DateHelper.formatDate(translateServiceMock, date_2_months_before, options),
80
+ ).toContain('MONTHS_AGO');
81
+ expect(
82
+ DateHelper.formatDate(translateServiceMock, date_2_months_before, options),
83
+ ).toContain('2');
84
+ if (mode == RelativeMode.large) {
85
+ expect(
86
+ DateHelper.formatDate(
87
+ translateServiceMock,
88
+ date_1_year_before,
89
+ options,
90
+ ),
91
+ ).not.toContain('YEARS_AGO');
92
+ } else {
93
+ expect(
94
+ DateHelper.formatDate(
95
+ translateServiceMock,
96
+ date_1_year_before,
97
+ options,
98
+ ),
99
+ ).toContain('YEARS_AGO');
100
+ expect(
101
+ DateHelper.formatDate(
102
+ translateServiceMock,
103
+ date_1_year_before,
104
+ options,
105
+ ),
106
+ ).toContain('1');
107
+ }
108
+ }
109
+ }
110
+ });
111
+ }
112
+ });
@@ -0,0 +1,197 @@
1
+ import { TranslateService } from '@ngx-translate/core';
2
+ import { isNumeric } from './isNumeric';
3
+ export enum RelativeMode {
4
+ off,
5
+ short,
6
+ medium,
7
+ large,
8
+ all,
9
+ }
10
+ export class FormatOptions {
11
+ showDate? = true;
12
+ showAlwaysTime? = false;
13
+ showSeconds? = false;
14
+ // @Deprecated
15
+ // this will be mapped to relativeLabels = MEDIUM
16
+ // use relativeLabels instead
17
+ useRelativeLabels? = true;
18
+ relativeLabels?: RelativeMode;
19
+ }
20
+
21
+ export class DateHelper {
22
+ /**
23
+ * Fill a date (day + month) string, e.g. 2 -> 02
24
+ * @param date
25
+ * @returns {string}
26
+ */
27
+ private static fillDate(date: number): string {
28
+ if (date < 10) return '0' + date;
29
+ return date + '';
30
+ }
31
+
32
+ /**
33
+ * Convert date to a unix timestamp
34
+ * @param date
35
+ * @returns {number}
36
+ */
37
+ public static convertDate(date: any) {
38
+ return new Date(date).getTime();
39
+ }
40
+
41
+ /**
42
+ * format a date with a given, fixed string
43
+ * For consistency, we use the patterns from
44
+ * https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
45
+ * @param date
46
+ * @param {string} format
47
+ * @returns {string}
48
+ */
49
+ public static formatDateByPattern(date: number | any, format: string): string {
50
+ if (!isNumeric(date)) {
51
+ return date;
52
+ }
53
+ let dateObject = new Date((date as number) * 1);
54
+ format = format.replace('y', '' + dateObject.getFullYear());
55
+ format = format.replace('M', '' + DateHelper.fillDate(dateObject.getMonth() + 1));
56
+ format = format.replace('d', '' + DateHelper.fillDate(dateObject.getDate()));
57
+ return format;
58
+ }
59
+
60
+ /**
61
+ * Format a date for the current language
62
+ */
63
+ public static formatDate(
64
+ translation: TranslateService,
65
+ date: number | any,
66
+ options: FormatOptions = new FormatOptions(),
67
+ ): string {
68
+ try {
69
+ if (options.useRelativeLabels && !options.relativeLabels) {
70
+ options.relativeLabels = RelativeMode.medium;
71
+ }
72
+ if (date == null) {
73
+ return null;
74
+ }
75
+ if (!isNumeric(date)) {
76
+ date = Date.parse(date);
77
+ }
78
+ let dateObject = new Date((date as number) * 1);
79
+ let dateToday = new Date();
80
+ let dateYesterday = new Date();
81
+ dateYesterday.setDate(dateYesterday.getDate() - 1);
82
+ let isToday = dateObject.toDateString() == dateToday.toDateString();
83
+ let isYesterday = dateObject.toDateString() == dateYesterday.toDateString();
84
+ let prefix = '';
85
+ let timeDiff = (dateToday.getTime() - dateObject.getTime()) / 1000;
86
+ let diffDays = Math.floor(timeDiff / (3600 * 24));
87
+ let diffMonths = new Date(timeDiff * 1000).getMonth();
88
+ let diffYears = new Date(timeDiff * 1000).getFullYear() - 1970;
89
+ let addDate = true;
90
+ let timeFormat = 'HH:mm';
91
+ if (options.showSeconds) {
92
+ timeFormat += ':ss';
93
+ }
94
+ if (timeDiff < 3600 * 6 && options.relativeLabels >= RelativeMode.short) {
95
+ if (timeDiff < 90) {
96
+ prefix = translation.instant('JUST_NOW', { seconds: timeDiff });
97
+ } else if (timeDiff < 60 * 100) {
98
+ prefix = translation.instant('MINUTES_AGO', {
99
+ minutes: Math.round(timeDiff / 60),
100
+ });
101
+ } else {
102
+ prefix = translation.instant('HOURS_AGO', {
103
+ hours: Math.round(timeDiff / (60 * 60)),
104
+ });
105
+ }
106
+ addDate = false;
107
+ timeFormat = '';
108
+ } else if (isToday && options.relativeLabels >= RelativeMode.short) {
109
+ prefix = translation.instant('TODAY');
110
+ addDate = false;
111
+ } else if (isYesterday && options.relativeLabels >= RelativeMode.medium) {
112
+ prefix = translation.instant('YESTERDAY');
113
+ addDate = false;
114
+ } else if (
115
+ (diffDays < 6 && options.relativeLabels >= RelativeMode.medium) ||
116
+ (diffDays < 45 && options.relativeLabels >= RelativeMode.large)
117
+ ) {
118
+ prefix = translation.instant('DAYS_AGO', { days: diffDays });
119
+ addDate = false;
120
+ if (!options.showAlwaysTime) timeFormat = '';
121
+ } else if (
122
+ diffYears === 0 &&
123
+ diffMonths < 12 &&
124
+ options.relativeLabels >= RelativeMode.large
125
+ ) {
126
+ prefix = translation.instant('MONTHS_AGO', { months: diffMonths });
127
+ addDate = false;
128
+ if (!options.showAlwaysTime) timeFormat = '';
129
+ } else if (options.relativeLabels === RelativeMode.all) {
130
+ prefix = translation.instant('YEARS_AGO', { years: diffYears });
131
+ addDate = false;
132
+ if (!options.showAlwaysTime) timeFormat = '';
133
+ } else {
134
+ if (!options.showAlwaysTime) timeFormat = '';
135
+ }
136
+
137
+ // ng2's dateformatter is super slow, but it doesn't matter, we just iterate it once :)
138
+ //return dateFormat+time;
139
+ let str = prefix;
140
+ if (addDate) {
141
+ if (translation.currentLang === 'en') {
142
+ str +=
143
+ dateObject.getFullYear() +
144
+ '-' +
145
+ DateHelper.fillDate(dateObject.getMonth() + 1) +
146
+ '-' +
147
+ DateHelper.fillDate(dateObject.getDate());
148
+ } else {
149
+ str +=
150
+ DateHelper.fillDate(dateObject.getDate()) +
151
+ '.' +
152
+ DateHelper.fillDate(dateObject.getMonth() + 1) +
153
+ '.' +
154
+ dateObject.getFullYear();
155
+ }
156
+ //str += DateFormatter.format(dateObject, Translation.getLanguage(), dateFormat).trim();
157
+ }
158
+ if (options.showDate == false) {
159
+ str = '';
160
+ }
161
+ // ie fixes, timeFormat not working
162
+ if (timeFormat) {
163
+ if (str) str += ', ';
164
+
165
+ //let timeValue=dateObject.toLocaleTimeString(Translation.getLanguage());
166
+ //let times=timeValue.split(":");
167
+ str += timeFormat
168
+ .replace('HH', DateHelper.fillDate(dateObject.getHours()))
169
+ .replace('mm', DateHelper.fillDate(dateObject.getMinutes()))
170
+ .replace('ss', DateHelper.fillDate(dateObject.getSeconds()));
171
+ }
172
+ return str;
173
+ /*
174
+ let dateString=prefix+" ";
175
+ if(dateFormat!=""){
176
+ dateString+=dateObject.toLocaleDateString(Translation.getLanguage())+" ";
177
+ }
178
+ if(time!=""){
179
+ dateString+=dateObject.toLocaleTimeString(Translation.getLanguage());
180
+ }
181
+ return dateString;
182
+ */
183
+ } catch (e) {
184
+ return date as any;
185
+ }
186
+ }
187
+ static getDateFromDatepicker(date: Date) {
188
+ return new Date(date.getTime() - date.getTimezoneOffset() * 60 * 1000);
189
+ }
190
+
191
+ static getDateForNewFile() {
192
+ return DateHelper.formatDate(null, new Date().getTime(), {
193
+ showAlwaysTime: true,
194
+ useRelativeLabels: false,
195
+ });
196
+ }
197
+ }