@dative-gpi/foundation-shared-components 1.0.65 → 1.0.67-map-edit
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/assets/images/map/snow.png +0 -0
- package/components/FSAccordionPanel.vue +40 -21
- package/components/FSBreadcrumbs.vue +21 -12
- package/components/FSButton.vue +11 -9
- package/components/FSCalendar.vue +50 -12
- package/components/FSCalendarTwin.vue +95 -43
- package/components/FSCard.vue +61 -9
- package/components/FSCardPlaceholder.vue +8 -5
- package/components/FSCheckbox.vue +5 -4
- package/components/FSChip.vue +73 -45
- package/components/FSChipGroup.vue +69 -0
- package/components/FSClickable.vue +11 -9
- package/components/FSClock.vue +30 -12
- package/components/FSCol.vue +11 -5
- package/components/FSDialog.vue +2 -1
- package/components/FSDialogContent.vue +12 -11
- package/components/FSDialogForm.vue +22 -2
- package/components/FSDialogFormBody.vue +50 -31
- package/components/FSDialogMenu.vue +17 -8
- package/components/FSDialogMultiFormBody.vue +23 -13
- package/components/FSDialogRemove.vue +7 -8
- package/components/FSDialogSubmit.vue +20 -11
- package/components/FSEditImageUI.vue +13 -5
- package/components/FSFadeOut.vue +53 -21
- package/components/FSForm.vue +10 -8
- package/components/FSGrid.vue +0 -1
- package/components/FSIcon.vue +2 -2
- package/components/FSIconCard.vue +68 -12
- package/components/FSInformationsMenu.vue +142 -0
- package/components/FSInstantPicker.vue +268 -0
- package/components/FSLink.vue +25 -9
- package/components/FSLoader.vue +28 -10
- package/components/FSMenu.vue +47 -0
- package/components/FSOptionGroup.vue +8 -8
- package/components/FSOptionItem.vue +4 -4
- package/components/FSOptionsMenu.vue +165 -0
- package/components/FSPagination.vue +1 -1
- package/components/FSPlayButtons.vue +72 -0
- package/components/FSProgressBar.vue +94 -0
- package/components/FSRadio.vue +5 -4
- package/components/FSRadioGroup.vue +3 -3
- package/components/FSRangePicker.vue +275 -0
- package/components/FSRangeSlider.vue +84 -0
- package/components/FSRouterLink.vue +42 -0
- package/components/FSSlideGroup.vue +19 -5
- package/components/FSSlider.vue +44 -79
- package/components/FSSpan.vue +12 -7
- package/components/FSSwitch.vue +44 -48
- package/components/FSTab.vue +15 -13
- package/components/FSTabs.vue +32 -7
- package/components/FSTag.vue +3 -3
- package/components/FSTagGroup.vue +6 -4
- package/components/FSText.vue +11 -7
- package/components/FSToggleSet.vue +7 -7
- package/components/FSWindow.vue +122 -5
- package/components/FSWrapGroup.vue +13 -1
- package/components/agenda/FSAgenda.vue +26 -7
- package/components/agenda/FSAgendaDialogCalendar.vue +2 -2
- package/components/agenda/FSAgendaHeader.vue +35 -10
- package/components/agenda/FSAgendaHorizontalEvent.vue +18 -6
- package/components/agenda/FSAgendaHoursRow.vue +48 -8
- package/components/agenda/FSAgendaVerticalEvent.vue +1 -1
- package/components/agenda/FSDayAgenda.vue +0 -1
- package/components/agenda/FSMonthAgenda.vue +1 -6
- package/components/agenda/FSSelectAgendaMode.vue +2 -2
- package/components/agenda/FSWeekAgenda.vue +5 -10
- package/components/autocompletes/FSAutoCompleteAddress.vue +25 -20
- package/components/autocompletes/FSAutocompleteLanguage.vue +7 -1
- package/components/autocompletes/FSAutocompleteTimeZone.vue +7 -1
- package/components/buttons/FSButtonAdd.vue +1 -1
- package/components/buttons/FSButtonAddLabel.vue +1 -1
- package/components/buttons/FSButtonCancel.vue +1 -1
- package/components/buttons/FSButtonCancelLabel.vue +1 -1
- package/components/buttons/FSButtonCheckbox.vue +4 -4
- package/components/buttons/FSButtonCopy.vue +1 -1
- package/components/buttons/FSButtonCopyLabel.vue +1 -1
- package/components/buttons/FSButtonDuplicate.vue +1 -1
- package/components/buttons/FSButtonDuplicateLabel.vue +1 -1
- package/components/buttons/FSButtonEdit.vue +1 -1
- package/components/buttons/FSButtonEditLabel.vue +1 -1
- package/components/buttons/FSButtonFile.vue +1 -1
- package/components/buttons/FSButtonFileLabel.vue +1 -1
- package/components/buttons/FSButtonNext.vue +1 -1
- package/components/buttons/FSButtonNextLabel.vue +1 -1
- package/components/buttons/FSButtonPrevious.vue +1 -1
- package/components/buttons/FSButtonPreviousLabel.vue +1 -1
- package/components/buttons/FSButtonRedo.vue +1 -1
- package/components/buttons/FSButtonRedoLabel.vue +1 -1
- package/components/buttons/FSButtonRemove.vue +1 -1
- package/components/buttons/FSButtonRemoveLabel.vue +1 -1
- package/components/buttons/FSButtonSave.vue +1 -1
- package/components/buttons/FSButtonSaveLabel.vue +1 -1
- package/components/buttons/FSButtonSearch.vue +1 -1
- package/components/buttons/FSButtonSearchLabel.vue +1 -1
- package/components/buttons/FSButtonUndo.vue +1 -1
- package/components/buttons/FSButtonUndoLabel.vue +1 -1
- package/components/buttons/FSButtonUpdate.vue +1 -1
- package/components/buttons/FSButtonUpdateLabel.vue +1 -1
- package/components/buttons/FSButtonValidate.vue +1 -1
- package/components/buttons/FSButtonValidateLabel.vue +1 -1
- package/components/calendar/FSSimpleCalendar.vue +145 -0
- package/components/calendar/FSSimpleCalendarHeader.vue +60 -0
- package/components/calendar/FSSimpleMonthSelector.vue +138 -0
- package/components/deviceOrganisations/FSConnectivity.vue +5 -3
- package/components/deviceOrganisations/FSStatus.vue +5 -3
- package/components/deviceOrganisations/FSStatusCard.vue +7 -9
- package/components/deviceOrganisations/FSStatusRichCard.vue +171 -0
- package/components/deviceOrganisations/FSWorstAlert.vue +24 -36
- package/components/deviceOrganisations/FSWorstAlertCard.vue +8 -47
- package/components/fields/FSAutocompleteField.vue +85 -82
- package/components/fields/FSAutocompleteTag.vue +1 -1
- package/components/fields/FSBaseField.vue +42 -25
- package/components/fields/FSClosableSearchField.vue +83 -0
- package/components/fields/FSColorField.vue +12 -10
- package/components/fields/FSCommentField.vue +28 -16
- package/components/fields/FSDateField.vue +13 -10
- package/components/fields/FSDateRangeField.vue +6 -5
- package/components/fields/FSDateTimeField.vue +14 -11
- package/components/fields/FSDateTimeRangeDialog.vue +160 -0
- package/components/fields/FSDateTimeRangeField.vue +23 -115
- package/components/fields/FSEntityFieldUI.vue +19 -16
- package/components/fields/FSGradientField.vue +5 -5
- package/components/fields/FSIconField.vue +16 -9
- package/components/fields/FSMagicConfigField.vue +15 -7
- package/components/fields/FSMagicField.vue +7 -2
- package/components/fields/FSNumberField.vue +8 -4
- package/components/fields/FSPasswordField.vue +7 -7
- package/components/fields/FSRichTextField.vue +78 -58
- package/components/fields/FSSearchField.vue +9 -115
- package/components/fields/FSSelectField.vue +69 -71
- package/components/fields/FSTagField.vue +9 -9
- package/components/fields/FSTermField.vue +69 -46
- package/components/fields/FSTextArea.vue +17 -11
- package/components/fields/FSTextField.vue +15 -10
- package/components/fields/FSTimeField.vue +14 -10
- package/components/fields/FSTimeRangeField.vue +310 -0
- package/components/fields/FSTimeStepField.vue +5 -5
- package/components/fields/FSTranslateField.vue +10 -10
- package/components/fields/FSTranslateRichTextField.vue +41 -20
- package/components/fields/FSTranslateTextArea.vue +10 -10
- package/components/fields/FSTreeViewField.vue +15 -13
- package/components/fields/periodicField/FSPeriodicDailyField.vue +7 -7
- package/components/fields/periodicField/FSPeriodicField.vue +15 -15
- package/components/fields/periodicField/FSPeriodicMonthlyField.vue +16 -16
- package/components/fields/periodicField/FSPeriodicWeeklyField.vue +28 -18
- package/components/fields/periodicField/FSPeriodicYearlyField.vue +12 -12
- package/components/lists/FSDataIteratorItem.vue +23 -67
- package/components/lists/FSDataTableUI.vue +198 -123
- package/components/lists/FSDraggable.vue +2 -2
- package/components/lists/FSFilterButton.vue +14 -16
- package/components/lists/FSHeaderButton.vue +11 -9
- package/components/lists/FSHiddenButton.vue +9 -9
- package/components/lists/FSLoadDataTable.vue +10 -7
- package/components/lists/FSSimpleList.vue +95 -88
- package/components/lists/FSSimpleListItem.vue +131 -0
- package/components/map/FSMap.vue +144 -158
- package/components/map/FSMapEditLocationAddress.vue +189 -0
- package/components/map/FSMapFeatureGroup.vue +7 -1
- package/components/map/FSMapLayerButton.vue +4 -3
- package/components/map/FSMapMarker.vue +103 -42
- package/components/map/FSMapMarkerClusterGroup.vue +32 -7
- package/components/map/FSMapOverlay.vue +44 -24
- package/components/map/FSMapPolygon.vue +16 -4
- package/components/map/FSMapTileLayer.vue +26 -9
- package/components/map/layers.ts +0 -0
- package/components/selects/FSSelectAutoRefresh.vue +8 -8
- package/components/selects/FSSelectDashboardVariableType.vue +4 -3
- package/components/selects/FSSelectDateSetting.vue +2 -2
- package/components/selects/FSSelectDays.vue +8 -8
- package/components/selects/FSSelectListMode.vue +2 -2
- package/components/selects/FSSelectMapLayer.vue +68 -0
- package/components/selects/FSSelectMonths.vue +13 -13
- package/components/selects/chartSelectors/FSAggregationSelector.vue +52 -0
- package/components/selects/chartSelectors/FSAxisTypeSelector.vue +49 -0
- package/components/selects/chartSelectors/FSDisplayAsSelector.vue +53 -0
- package/components/selects/chartSelectors/FSFilterTypeSelector.vue +54 -0
- package/components/selects/chartSelectors/FSHeatmapRuleSelector.vue +54 -0
- package/components/selects/chartSelectors/FSOperationOnSelector.vue +53 -0
- package/components/selects/chartSelectors/FSPlanningTypeSelector.vue +53 -0
- package/components/selects/chartSelectors/FSPlotPerSelector.vue +52 -0
- package/components/selects/chartSelectors/FSSelectEntityType.vue +59 -0
- package/components/selects/chartSelectors/FSSerieTypeSelector.vue +53 -0
- package/components/tiles/FSAlertTileUI.vue +90 -0
- package/components/tiles/FSChartTileUI.vue +61 -52
- package/components/tiles/FSCommentTileUI.vue +38 -13
- package/components/tiles/FSDashboardOrganisationTypeTileUI.vue +14 -2
- package/components/tiles/FSDashboardShallowTileUI.vue +14 -2
- package/components/tiles/FSDeviceOrganisationTileUI.vue +0 -6
- package/components/tiles/FSEntityCountBadge.vue +72 -0
- package/components/tiles/FSFolderTileUI.vue +38 -4
- package/components/tiles/FSGroupTileUI.vue +32 -136
- package/components/tiles/FSLoadTile.vue +16 -10
- package/components/tiles/FSLocationTileUI.vue +45 -63
- package/components/tiles/FSServiceAccountOrganisationTileUI.vue +0 -6
- package/components/tiles/FSSimpleTileUI.vue +30 -24
- package/components/tiles/FSTile.vue +46 -39
- package/components/tiles/FSUserOrganisationTileUI.vue +1 -7
- package/components/tiles/FSUserTileUI.vue +119 -0
- package/components/toggleSets/FSToggleSetPosition.vue +1 -1
- package/components/views/FSBaseView.vue +64 -0
- package/components/views/FSEntityView.vue +12 -146
- package/components/views/FSSimpleView.vue +29 -0
- package/components/views/desktop/FSBaseDefaultDesktopView.vue +135 -0
- package/components/views/desktop/FSBaseDesktopView.vue +53 -0
- package/components/views/desktop/FSBaseEntityDesktopView.vue +211 -0
- package/components/views/mobile/FSBaseDefaultMobileView.vue +133 -0
- package/components/views/mobile/FSBaseEntityMobileView.vue +206 -0
- package/components/views/mobile/FSBaseMobileView.vue +53 -0
- package/composables/index.ts +1 -0
- package/composables/useAddress.ts +40 -8
- package/composables/useBreakpoints.ts +40 -4
- package/composables/useColors.ts +16 -7
- package/composables/useMagicFieldProvider.ts +1 -0
- package/composables/useMapLayers.ts +69 -0
- package/composables/useSlots.ts +2 -1
- package/models/colors.ts +2 -1
- package/models/deviceAlerts.ts +1 -0
- package/models/magicFields.ts +1 -0
- package/models/map.ts +12 -10
- package/models/rules.ts +5 -2
- package/models/tables.ts +2 -1
- package/models/variableNode.ts +8 -5
- package/package.json +5 -5
- package/styles/components/fs_agenda.scss +4 -0
- package/styles/components/fs_agenda_event.scss +1 -1
- package/styles/components/fs_agenda_hours_row.scss +0 -8
- package/styles/components/fs_autocomplete_field.scss +0 -13
- package/styles/components/fs_breadcrumbs.scss +18 -36
- package/styles/components/fs_button.scss +7 -5
- package/styles/components/fs_calendar.scss +1 -0
- package/styles/components/fs_card.scss +9 -0
- package/styles/components/fs_chip.scss +13 -7
- package/styles/components/fs_clickable.scss +16 -23
- package/styles/components/fs_clock.scss +0 -10
- package/styles/components/fs_col.scss +1 -1
- package/styles/components/fs_color_field.scss +0 -4
- package/styles/components/fs_data_table.scss +6 -9
- package/styles/components/fs_dialog.scss +4 -10
- package/styles/components/fs_dialog_menu.scss +4 -2
- package/styles/components/fs_draggable.scss +0 -5
- package/styles/components/fs_fade_out.scss +10 -2
- package/styles/components/fs_filter_button.scss +1 -1
- package/styles/components/fs_hidden_button.scss +2 -7
- package/styles/components/fs_image_card.scss +6 -4
- package/styles/components/fs_magic_config_field.scss +1 -2
- package/styles/components/fs_map.scss +57 -17
- package/styles/components/fs_meta_field.scss +3 -5
- package/styles/components/fs_password_field.scss +4 -2
- package/styles/components/fs_progress_bar.scss +14 -0
- package/styles/components/fs_radio.scss +0 -11
- package/styles/components/fs_rich_text_field.scss +1 -10
- package/styles/components/fs_select_field.scss +4 -13
- package/styles/components/fs_slide_group.scss +7 -0
- package/styles/components/fs_slider.scss +0 -40
- package/styles/components/fs_span.scss +13 -5
- package/styles/components/fs_status_rich_card.scss +6 -0
- package/styles/components/fs_tabs.scss +18 -37
- package/styles/components/fs_tag.scss +8 -22
- package/styles/components/fs_text_area.scss +2 -21
- package/styles/components/fs_tile.scss +0 -19
- package/styles/components/fs_window.scss +3 -1
- package/styles/components/fs_wrap_group.scss +7 -0
- package/styles/components/index.scss +2 -6
- package/styles/globals/index.scss +1 -5
- package/styles/globals/overrides.scss +26 -54
- package/styles/globals/scrollbars.scss +8 -0
- package/styles/globals/text_fonts.scss +18 -66
- package/styles/globals/touchscreen.scss +2 -2
- package/tools/alertsTools.ts +94 -18
- package/tools/chartsTools.ts +155 -16
- package/tools/index.ts +3 -1
- package/tools/reportsTools.ts +38 -0
- package/tools/timeRangeTools.ts +125 -0
- package/utils/badge.ts +9 -5
- package/utils/filter.ts +4 -1
- package/utils/index.ts +2 -0
- package/utils/leafletMarkers.ts +4 -4
- package/utils/operations.ts +108 -0
- package/utils/picker.ts +40 -0
- package/utils/sort.ts +2 -2
- package/utils/time.ts +13 -13
- package/components/fields/FSTimeSlotField.vue +0 -250
- package/components/views/FSEntityHeader.vue +0 -343
- package/components/views/FSListHeader.vue +0 -83
- package/components/views/FSListView.vue +0 -83
- package/components/views/FSSkeletonView.vue +0 -100
- package/styles/components/fs_data_iterator_item.scss +0 -33
- package/styles/components/fs_icon_field.scss +0 -12
- package/styles/components/fs_search_field.scss +0 -3
- package/styles/components/fs_tag_field.scss +0 -8
- package/styles/components/fs_time_field.scss +0 -12
- package/styles/components/fs_timeslot_field.scss +0 -12
- package/styles/globals/breakpoints.scss +0 -20
- package/styles/globals/fixes.scss +0 -5
package/tools/alertsTools.ts
CHANGED
|
@@ -1,31 +1,59 @@
|
|
|
1
1
|
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
2
2
|
import { AlertStatus, Criticity } from "@dative-gpi/foundation-shared-domain/enums";
|
|
3
|
-
import { ColorEnum } from "
|
|
3
|
+
import { ColorEnum } from "../models";
|
|
4
|
+
import { getTimeBestString } from "../utils";
|
|
4
5
|
|
|
5
6
|
const { $tr } = useTranslationsProvider();
|
|
6
7
|
|
|
7
8
|
export const AlertTools = {
|
|
8
9
|
statusIcon(value: AlertStatus): string {
|
|
9
10
|
switch (value) {
|
|
10
|
-
case AlertStatus.Pending: return "mdi-timer-
|
|
11
|
-
case AlertStatus.Untriggered: return "mdi-
|
|
12
|
-
case AlertStatus.Unresolved: return "mdi-
|
|
13
|
-
case AlertStatus.Resolved: return "mdi-check-circle
|
|
14
|
-
case AlertStatus.Expired: return "mdi-clock-outline";
|
|
15
|
-
case AlertStatus.Triggered: return "mdi-
|
|
11
|
+
case AlertStatus.Pending: return "mdi-timer-sand";
|
|
12
|
+
case AlertStatus.Untriggered: return "mdi-close-octagon";
|
|
13
|
+
case AlertStatus.Unresolved: return "mdi-cancel";
|
|
14
|
+
case AlertStatus.Resolved: return "mdi-check-circle";
|
|
15
|
+
case AlertStatus.Expired: return "mdi-timeline-clock-outline";
|
|
16
|
+
case AlertStatus.Triggered: return "mdi-timer-sand";
|
|
16
17
|
case AlertStatus.Abandoned: return "mdi-cancel"
|
|
17
18
|
default: return "";
|
|
18
19
|
}
|
|
19
20
|
},
|
|
20
21
|
statusLabel(value: AlertStatus): string {
|
|
21
22
|
switch (value) {
|
|
22
|
-
case AlertStatus.Pending:
|
|
23
|
-
|
|
24
|
-
case AlertStatus.
|
|
25
|
-
|
|
26
|
-
case AlertStatus.
|
|
27
|
-
|
|
28
|
-
case AlertStatus.
|
|
23
|
+
case AlertStatus.Pending:
|
|
24
|
+
return $tr('ui.alert-status.pending', 'Pending');
|
|
25
|
+
case AlertStatus.Untriggered:
|
|
26
|
+
return $tr('ui.alert-status.untriggered', 'Untriggered');
|
|
27
|
+
case AlertStatus.Unresolved:
|
|
28
|
+
return $tr('ui.alert-status.unresolved', 'Unresolved');
|
|
29
|
+
case AlertStatus.Resolved:
|
|
30
|
+
return $tr('ui.alert-status.resolved', 'Resolved');
|
|
31
|
+
case AlertStatus.Expired:
|
|
32
|
+
return $tr('ui.alert-status.expired', 'Expired');
|
|
33
|
+
case AlertStatus.Triggered:
|
|
34
|
+
return $tr('ui.alert-status.triggered', 'Triggered');
|
|
35
|
+
case AlertStatus.Abandoned:
|
|
36
|
+
return $tr('ui.alert-status.abandoned', 'Abandoned');
|
|
37
|
+
default: return "";
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
statusAlternativeColor(value: AlertStatus): string {
|
|
41
|
+
switch (value) {
|
|
42
|
+
case AlertStatus.Pending:
|
|
43
|
+
case AlertStatus.Unresolved:
|
|
44
|
+
case AlertStatus.Triggered: return "#da2d2d";
|
|
45
|
+
default: return "#1e56e5";
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
statusAlternativeIcon(value: AlertStatus): string {
|
|
49
|
+
switch (value) {
|
|
50
|
+
case AlertStatus.Pending: return "timer";
|
|
51
|
+
case AlertStatus.Untriggered: return "timer_off";
|
|
52
|
+
case AlertStatus.Unresolved: return "error_outline";
|
|
53
|
+
case AlertStatus.Resolved: return "check_circle_outline";
|
|
54
|
+
case AlertStatus.Expired: return "schedule";
|
|
55
|
+
case AlertStatus.Triggered: return "error_outline";
|
|
56
|
+
case AlertStatus.Abandoned: return "block"
|
|
29
57
|
default: return "";
|
|
30
58
|
}
|
|
31
59
|
},
|
|
@@ -46,9 +74,57 @@ export const AlertTools = {
|
|
|
46
74
|
},
|
|
47
75
|
criticityLabel(value: Criticity): string {
|
|
48
76
|
switch (value) {
|
|
49
|
-
case Criticity.
|
|
50
|
-
case Criticity.
|
|
51
|
-
|
|
77
|
+
case Criticity.Information: return $tr('ui.common.information', 'Information');
|
|
78
|
+
case Criticity.Warning: return $tr('ui.common.warning', 'Warning');
|
|
79
|
+
case Criticity.Error: return $tr('ui.common.error', 'Error');
|
|
80
|
+
default: return $tr("ui.common.none", "None");
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
statusColor(status: AlertStatus): ColorEnum {
|
|
84
|
+
switch (status) {
|
|
85
|
+
case AlertStatus.Pending:
|
|
86
|
+
return ColorEnum.Warning;
|
|
87
|
+
case AlertStatus.Expired:
|
|
88
|
+
case AlertStatus.Abandoned:
|
|
89
|
+
return ColorEnum.Dark;
|
|
90
|
+
case AlertStatus.Unresolved:
|
|
91
|
+
case AlertStatus.Triggered:
|
|
92
|
+
return ColorEnum.Error;
|
|
93
|
+
case AlertStatus.Resolved:
|
|
94
|
+
case AlertStatus.Untriggered:
|
|
95
|
+
return ColorEnum.Success;
|
|
96
|
+
default:
|
|
97
|
+
return ColorEnum.Warning;
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
formatValue(value: string) {
|
|
102
|
+
const n = parseFloat(value);
|
|
103
|
+
|
|
104
|
+
if (isNaN(n)) {
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (Number.isInteger(n)) {
|
|
109
|
+
return n;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
return n.toFixed(2);
|
|
52
113
|
}
|
|
53
114
|
}
|
|
54
|
-
|
|
115
|
+
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export const prettyDuration = (n: number | undefined) => {
|
|
119
|
+
if (n == null) { return "00m 00s"; }
|
|
120
|
+
const day = Math.floor(n / 24 / 60 / 60);
|
|
121
|
+
const hours = Math.floor((n - day * 24 * 60 * 60) / 3600);
|
|
122
|
+
const minutes = Math.floor((n - day * 24 * 60 * 60 - hours * 60 * 60) / 60);
|
|
123
|
+
const seconds = Math.floor(n - day * 24 * 60 * 60 - hours * 60 * 60 - minutes * 60);
|
|
124
|
+
|
|
125
|
+
return day > 0 ?
|
|
126
|
+
`${getTimeBestString(day * 24 * 60 * 60)} ${hours > 0 ? getTimeBestString(hours * 60 * 60) : ''} ${minutes > 0 ? getTimeBestString(minutes * 60) : ''} ${getTimeBestString(seconds)}`
|
|
127
|
+
: hours > 0
|
|
128
|
+
? `${getTimeBestString(hours * 60 * 60)} ${minutes > 0 ? getTimeBestString(minutes * 60) : ''} ${getTimeBestString(seconds)}`
|
|
129
|
+
: `${minutes > 0 ? getTimeBestString(minutes * 60) : ''} ${getTimeBestString(seconds)}`;
|
|
130
|
+
};
|
package/tools/chartsTools.ts
CHANGED
|
@@ -1,31 +1,60 @@
|
|
|
1
|
-
import { AxisType, ColorSets, SerieType, ChartType, TimeUnit } from "@dative-gpi/foundation-shared-domain/enums";
|
|
1
|
+
import { AxisType, ColorSets, SerieType, ChartType, TimeUnit, ChartOrigin, AggregationType, DisplayAs, FilterType, HeatmapRule, OperationOn, PlanningType, PlotPer, ApplicationScope } from "@dative-gpi/foundation-shared-domain/enums";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { getEnumEntries } from "@dative-gpi/foundation-shared-domain/tools";
|
|
4
4
|
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
5
|
+
import { ColorEnum, type ColorBase } from "../models";
|
|
5
6
|
|
|
6
7
|
const { $tr } = useTranslationsProvider();
|
|
7
8
|
|
|
9
|
+
export const chartOriginLabel = (type: ChartOrigin): string => {
|
|
10
|
+
switch (type) {
|
|
11
|
+
case ChartOrigin.None: return $tr("ui.common.none", "None");
|
|
12
|
+
case ChartOrigin.Organisation: return $tr("ui.common.custom", "Custom");
|
|
13
|
+
case ChartOrigin.OrganisationType: return $tr("ui.common.shared", "Shared");
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const applicationScopeLabel = (type: ApplicationScope): string => {
|
|
18
|
+
switch (type) {
|
|
19
|
+
case ApplicationScope.None:
|
|
20
|
+
return $tr("ui.common.none", "None");
|
|
21
|
+
case ApplicationScope.Organisation:
|
|
22
|
+
return $tr("ui.common.custom", "Custom");
|
|
23
|
+
case ApplicationScope.OrganisationType:
|
|
24
|
+
return $tr("ui.common.shared", "Shared");
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
export const chartOriginColor = (type: ChartOrigin): ColorBase => {
|
|
30
|
+
switch (type) {
|
|
31
|
+
case ChartOrigin.None: return ColorEnum.Error;
|
|
32
|
+
case ChartOrigin.Organisation: return ColorEnum.Primary;
|
|
33
|
+
case ChartOrigin.OrganisationType: return ColorEnum.Warning;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
|
|
8
37
|
export const chartTypeLabel = (value: ChartType): string => {
|
|
9
38
|
switch (value) {
|
|
10
|
-
case ChartType.Gauge: return $tr("ui.
|
|
11
|
-
case ChartType.Heatmap: return $tr("ui.
|
|
12
|
-
case ChartType.Pie: return $tr("ui.
|
|
13
|
-
case ChartType.ScoreCard: return $tr("ui.
|
|
14
|
-
case ChartType.Slider: return $tr("ui.
|
|
15
|
-
case ChartType.Table: return $tr("ui.
|
|
16
|
-
case ChartType.XY: return $tr("ui.
|
|
39
|
+
case ChartType.Gauge: return $tr("ui.chart-type.gauge", "Gauge");
|
|
40
|
+
case ChartType.Heatmap: return $tr("ui.chart-type.heatmap", "Heatmap");
|
|
41
|
+
case ChartType.Pie: return $tr("ui.chart-type.pie", "Pie");
|
|
42
|
+
case ChartType.ScoreCard: return $tr("ui.chart-type.score-card", "Score card");
|
|
43
|
+
case ChartType.Slider: return $tr("ui.chart-type.slider", "Slider");
|
|
44
|
+
case ChartType.Table: return $tr("ui.chart-type.table", "Table");
|
|
45
|
+
case ChartType.XY: return $tr("ui.chart-type.xy", "XY");
|
|
17
46
|
default: return $tr("ui.common.none", "None");
|
|
18
47
|
}
|
|
19
48
|
}
|
|
20
49
|
|
|
21
50
|
export const colorSetLabel = (value: ColorSets | number): string => {
|
|
22
51
|
switch (value) {
|
|
23
|
-
case ColorSets.Default: return $tr("ui.
|
|
24
|
-
case ColorSets.Grafana: return $tr("ui.
|
|
25
|
-
case ColorSets.Armytage: return $tr("ui.
|
|
26
|
-
case ColorSets.Hash: return $tr("ui.
|
|
27
|
-
case ColorSets.Kelly: return $tr("ui.
|
|
28
|
-
case ColorSets.ZeileisHornikMurrell: return $tr("ui.
|
|
52
|
+
case ColorSets.Default: return $tr("ui.color-sets.am-charts", "Am Charts");
|
|
53
|
+
case ColorSets.Grafana: return $tr("ui.color-sets.grafana", "Grafana");
|
|
54
|
+
case ColorSets.Armytage: return $tr("ui.color-sets.armytage", "High contrast (26 colors)");
|
|
55
|
+
case ColorSets.Hash: return $tr("ui.color-sets.hash", "Hash");
|
|
56
|
+
case ColorSets.Kelly: return $tr("ui.color-sets.kelly", "High contrast (22 colors)");
|
|
57
|
+
case ColorSets.ZeileisHornikMurrell: return $tr("ui.color-sets.zeileis", "Colorblind accessible");
|
|
29
58
|
default: return $tr("ui.common.none", "None");
|
|
30
59
|
}
|
|
31
60
|
}
|
|
@@ -66,6 +95,115 @@ export const serieTypeIcon = (serieType: SerieType): string => {
|
|
|
66
95
|
}
|
|
67
96
|
}
|
|
68
97
|
|
|
98
|
+
export const aggregationTypeLabel = (aggregationType: AggregationType): string => {
|
|
99
|
+
switch (aggregationType) {
|
|
100
|
+
case AggregationType.Sum: return $tr("ui.aggregation-type.sum", "Sum");
|
|
101
|
+
case AggregationType.Cardinal: return $tr("ui.aggregation-type.cardinal", "Cardinal");
|
|
102
|
+
case AggregationType.Mean: return $tr("ui.aggregation-type.mean", "Mean");
|
|
103
|
+
case AggregationType.Median: return $tr("ui.aggregation-type.median", "Median");
|
|
104
|
+
case AggregationType.First: return $tr("ui.aggregation-type.first", "First");
|
|
105
|
+
case AggregationType.Last: return $tr("ui.aggregation.last", "Last");
|
|
106
|
+
case AggregationType.Difference: return $tr("ui.aggregation-type.difference", "Difference");
|
|
107
|
+
case AggregationType.Minimum: return $tr("ui.common.minimum", "Minimum");
|
|
108
|
+
case AggregationType.Maximum: return $tr("ui.common.maximum", "Maximum");
|
|
109
|
+
case AggregationType.Range: return $tr("ui.aggregation-type.range", "Range");
|
|
110
|
+
default: return $tr("ui.common.none", "None");
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const axisTypeLabel = (axisType: AxisType | number): string => {
|
|
115
|
+
switch (axisType) {
|
|
116
|
+
case AxisType.Date: return $tr("ui.common.date", "Date");
|
|
117
|
+
case AxisType.Value: return $tr("ui.common.value", "Value");
|
|
118
|
+
case AxisType.Category: return $tr("ui.common.category", "Category");
|
|
119
|
+
default: return $tr("ui.common.none", "None");
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export const displayAsLabel = (display: DisplayAs | number): string => {
|
|
124
|
+
switch (display) {
|
|
125
|
+
case DisplayAs.Bars: return $tr("ui.common.bars", "Bars");
|
|
126
|
+
case DisplayAs.Lines: return $tr("ui.common.lines", "Lines");
|
|
127
|
+
case DisplayAs.Points: return $tr("ui.common.points", "Points");
|
|
128
|
+
default: return $tr("ui.common.none", "None");
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const filterTypeLabel = (filterType: FilterType | number): string => {
|
|
133
|
+
switch (filterType) {
|
|
134
|
+
case FilterType.Contains: return $tr("ui.common.contains", "contains");
|
|
135
|
+
case FilterType.Different: return "≠";
|
|
136
|
+
case FilterType.EndsWith: return $tr("ui.filter-type.ends-with", "ends with");
|
|
137
|
+
case FilterType.Equal: return "=";
|
|
138
|
+
case FilterType.Less: return "<";
|
|
139
|
+
case FilterType.LessOrEqual: return "≤";
|
|
140
|
+
case FilterType.More: return ">";
|
|
141
|
+
case FilterType.MoreOrEqual: return "≥";
|
|
142
|
+
case FilterType.StartsWith: return $tr("ui.filter-type.starts-with", "start with");
|
|
143
|
+
default: return $tr("ui.common.none", "None");
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
export const heatmapRuleLabel = (heatMap: HeatmapRule | number): string => {
|
|
148
|
+
switch (heatMap) {
|
|
149
|
+
case HeatmapRule.Gradient: return $tr("ui.common.gradient", "Gradient");
|
|
150
|
+
case HeatmapRule.Ranges: return $tr("ui.common.ranges", "Ranges");
|
|
151
|
+
case HeatmapRule.Fixed: return $tr("ui.common.fixed", "Fixed");
|
|
152
|
+
default: return $tr("ui.common.none", "None");
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export const operationOnLabel = (operationOn: OperationOn | number): string => {
|
|
157
|
+
switch (operationOn) {
|
|
158
|
+
case OperationOn.SameEntity: return $tr("ui.operation-on.same-entity", "Same entity");
|
|
159
|
+
case OperationOn.SameGroup: return $tr("ui.operation-on.same-group", "Same group");
|
|
160
|
+
case OperationOn.SameGroupAndEntity: return $tr("ui.operation-on.same-group-entity", "Same group and entity");
|
|
161
|
+
default: return $tr("ui.common.none", "None");
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
export const planningTypeLabel = (planningType: PlanningType | number): string => {
|
|
166
|
+
switch (planningType) {
|
|
167
|
+
case PlanningType.UntilNext: return $tr("ui.planning-type.until-next", "Until next");
|
|
168
|
+
case PlanningType.ElapsedTime: return $tr("ui.planning-type.elapsed-time", "Elapsed time");
|
|
169
|
+
case PlanningType.SinglePoint: return $tr("ui.planning-type.single-point", "Single point");
|
|
170
|
+
default: return $tr("ui.common.none", "None");
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export const plotPerLabel = (plotper: PlotPer | number): string => {
|
|
175
|
+
switch (plotper) {
|
|
176
|
+
case PlotPer.SinglePlot: return $tr("ui.plot-per.single-slot", "Single slot");
|
|
177
|
+
case PlotPer.Model: return $tr("ui.common.model", "Model");
|
|
178
|
+
case PlotPer.Group: return $tr("ui.common.group", "Group");
|
|
179
|
+
case PlotPer.Location: return $tr("ui.common.location", "Location");
|
|
180
|
+
case PlotPer.Device: return $tr("ui.common.device", "Device");
|
|
181
|
+
default: return $tr("ui.common.none", "None");
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export const serieTypeLabel = (serieType: SerieType): string => {
|
|
186
|
+
switch (serieType) {
|
|
187
|
+
case SerieType.Lines: return $tr("ui.common.lines", "Lines");
|
|
188
|
+
case SerieType.Area: return $tr("ui.common.area", "Area");
|
|
189
|
+
case SerieType.Range: return $tr("ui.common.range", "Range");
|
|
190
|
+
case SerieType.Histogram: return $tr("ui.common.histogram", "Histogram");
|
|
191
|
+
case SerieType.Operation: return $tr("ui.common.operation", "Operation");
|
|
192
|
+
case SerieType.Planning: return $tr("ui.common.planning", "Planning");
|
|
193
|
+
case SerieType.ScatterPlot: return $tr("ui.common.scatter-plot", "Scatter plot");
|
|
194
|
+
case SerieType.Top: return $tr("ui.serie-type.top", "Top");
|
|
195
|
+
case SerieType.Bars: return $tr("ui.common.bars", "Bars");
|
|
196
|
+
case SerieType.StackedBars: return $tr("ui.common.stacked-bars", "Stacked bars");
|
|
197
|
+
case SerieType.Pie: return $tr("ui.common.pie", "Pie");
|
|
198
|
+
case SerieType.Heatmap: return $tr('ui.common.heatmap', 'Heatmap');
|
|
199
|
+
case SerieType.Slider: return $tr("ui.common.slider", "Slider");
|
|
200
|
+
case SerieType.Gauge: return $tr("ui.common.gauge", "Gauge");
|
|
201
|
+
case SerieType.ScoreCard: return $tr("ui.common.score-card", "Score card");
|
|
202
|
+
case SerieType.Table: return $tr("ui.serie-type.table", "Table");
|
|
203
|
+
default: return "";
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
69
207
|
export const showModifiers = (serieType: SerieType) => {
|
|
70
208
|
switch (serieType) {
|
|
71
209
|
case SerieType.Lines:
|
|
@@ -297,4 +435,5 @@ export const timeMillisecond = (value: number | null | undefined, unit: TimeUnit
|
|
|
297
435
|
case TimeUnit.Year: return value * 31536000000;
|
|
298
436
|
default: return 0;
|
|
299
437
|
}
|
|
300
|
-
}
|
|
438
|
+
}
|
|
439
|
+
|
package/tools/index.ts
CHANGED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
2
|
+
import { ColorEnum } from "../models";
|
|
3
|
+
import { JobState } from "@dative-gpi/foundation-shared-domain/enums";
|
|
4
|
+
|
|
5
|
+
const { $tr } = useTranslationsProvider();
|
|
6
|
+
|
|
7
|
+
export const getColorByState = (state: number | JobState | undefined) => {
|
|
8
|
+
switch (state) {
|
|
9
|
+
case JobState.Succeeded:
|
|
10
|
+
return ColorEnum.Success;
|
|
11
|
+
case JobState.Failed:
|
|
12
|
+
return ColorEnum.Error;
|
|
13
|
+
default:
|
|
14
|
+
return ColorEnum.Primary;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const getIconByState = (state: number | JobState | undefined) => {
|
|
19
|
+
switch (state) {
|
|
20
|
+
case JobState.Succeeded:
|
|
21
|
+
return 'mdi-check-circle-outline';
|
|
22
|
+
case JobState.Failed:
|
|
23
|
+
return 'mdi-alert-circle-outline';
|
|
24
|
+
default:
|
|
25
|
+
return 'mdi-alert-circle-outline';
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const getLabelByState = (state: number | JobState | undefined) => {
|
|
30
|
+
switch (state) {
|
|
31
|
+
case JobState.Succeeded:
|
|
32
|
+
return $tr('ui.common.success', 'Success');
|
|
33
|
+
case JobState.Failed:
|
|
34
|
+
return $tr('ui.common.error', 'Error');
|
|
35
|
+
default:
|
|
36
|
+
return $tr('ui.common.executed', 'Executed');
|
|
37
|
+
}
|
|
38
|
+
};
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { DateType, Days } from "@dative-gpi/foundation-shared-domain/enums";
|
|
2
|
+
import { useAppTimeZone } from "@dative-gpi/foundation-shared-services/composables";
|
|
3
|
+
|
|
4
|
+
import { useTranslations as useTranslationsProvider } from "@dative-gpi/bones-ui/composables";
|
|
5
|
+
|
|
6
|
+
const { $tr } = useTranslationsProvider();
|
|
7
|
+
|
|
8
|
+
const { getUserOffset } = useAppTimeZone();
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
export const applyOffset = (r: DateTimeRange, negative: boolean) => {
|
|
12
|
+
const range: DateTimeRange = {
|
|
13
|
+
startDay: r.startDay,
|
|
14
|
+
startHour: r.startHour,
|
|
15
|
+
startMinute: r.startMinute,
|
|
16
|
+
endDay: r.endDay,
|
|
17
|
+
endHour: r.endHour,
|
|
18
|
+
endMinute: r.endMinute,
|
|
19
|
+
variant: r.variant
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
if (r.variant == DateType.UTC) {
|
|
23
|
+
let innerStartHour = 0;
|
|
24
|
+
let innerEndHour = 0;
|
|
25
|
+
|
|
26
|
+
if (negative) {
|
|
27
|
+
innerStartHour = r.startHour - getUserOffset() / 1000 / 60 / 60;
|
|
28
|
+
innerEndHour = r.endHour - getUserOffset() / 1000 / 60 / 60;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
innerStartHour = r.startHour + getUserOffset() / 1000 / 60 / 60;
|
|
32
|
+
innerEndHour = r.endHour + getUserOffset() / 1000 / 60 / 60;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (![Days.AllDays].includes(r.startDay)) {
|
|
36
|
+
if (innerStartHour > 23) {
|
|
37
|
+
range.startDay = (r.startDay + 1) % 7;
|
|
38
|
+
range.startHour = innerStartHour - 24;
|
|
39
|
+
}
|
|
40
|
+
else if (innerStartHour < 0) {
|
|
41
|
+
range.startDay = (r.startDay + 6) % 7;
|
|
42
|
+
range.startHour = innerStartHour + 24;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
range.startHour = innerStartHour;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (innerEndHour > 23) {
|
|
49
|
+
range.endDay = (r.endDay + 1) % 7;
|
|
50
|
+
range.endHour = innerEndHour - 24;
|
|
51
|
+
}
|
|
52
|
+
else if (innerEndHour < 0) {
|
|
53
|
+
range.endDay = (r.endDay + 6) % 7;
|
|
54
|
+
range.endHour = innerEndHour + 24;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
range.endHour = innerEndHour;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
if (innerStartHour > 23) {
|
|
62
|
+
range.startHour = innerStartHour - 24;
|
|
63
|
+
}
|
|
64
|
+
else if (innerStartHour < 0) {
|
|
65
|
+
range.startHour = innerStartHour + 24;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
range.startHour = innerStartHour;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (innerEndHour > 23) {
|
|
72
|
+
range.endHour = innerEndHour - 24;
|
|
73
|
+
}
|
|
74
|
+
else if (innerEndHour < 0) {
|
|
75
|
+
range.endHour = innerEndHour + 24;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
range.endHour = innerEndHour;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
startDay: range.startDay,
|
|
83
|
+
startHour: range.startHour,
|
|
84
|
+
startMinute: r.startMinute,
|
|
85
|
+
endDay: range.endDay,
|
|
86
|
+
endHour: range.endHour,
|
|
87
|
+
endMinute: range.endMinute,
|
|
88
|
+
variant: range.variant
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return r;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export interface DateTimeRange {
|
|
97
|
+
startDay: Days;
|
|
98
|
+
startHour: number;
|
|
99
|
+
startMinute: number;
|
|
100
|
+
endDay: Days;
|
|
101
|
+
endHour: number;
|
|
102
|
+
endMinute: number;
|
|
103
|
+
variant: DateType;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const dayLabel = (day: Days | number): string => {
|
|
107
|
+
switch (day) {
|
|
108
|
+
case Days.Monday:
|
|
109
|
+
return $tr("ui.common.monday", "Monday");
|
|
110
|
+
case Days.Tuesday:
|
|
111
|
+
return $tr("ui.common.tuesday", "Tuesday");
|
|
112
|
+
case Days.Wednesday:
|
|
113
|
+
return $tr("ui.common.wednesday", "Wednesday");
|
|
114
|
+
case Days.Thursday:
|
|
115
|
+
return $tr("ui.common.thursday", "Thursday");
|
|
116
|
+
case Days.Friday:
|
|
117
|
+
return $tr("ui.common.friday", "Friday");
|
|
118
|
+
case Days.Saturday:
|
|
119
|
+
return $tr("ui.common.saturday", "Saturday");
|
|
120
|
+
case Days.Sunday:
|
|
121
|
+
return $tr("ui.common.sunday", "Sunday");
|
|
122
|
+
default:
|
|
123
|
+
return $tr("ui.common.all-days", "All days");
|
|
124
|
+
}
|
|
125
|
+
}
|
package/utils/badge.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
export const
|
|
1
|
+
export const capNumberToString = (value: number, maximum: number = 99): string => {
|
|
2
|
+
if (value > maximum) {
|
|
3
|
+
return `${maximum}+`;
|
|
4
|
+
}
|
|
5
|
+
return `${value.toString()}`;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const getBadgeFromNumber = (value: number, parenthesis: boolean = false, maximum: number = 99): string => {
|
|
2
9
|
if (value < 1) {
|
|
3
10
|
return "";
|
|
4
11
|
}
|
|
5
|
-
|
|
6
|
-
return `${parenthesis ? '(' : ''}99+${parenthesis ? ')' : ''}`;
|
|
7
|
-
}
|
|
8
|
-
return `${parenthesis ? '(' : ''}${value.toString()}${parenthesis ? ')' : ''}`;
|
|
12
|
+
return parenthesis ? `(${capNumberToString(value, maximum)})` : capNumberToString(value, maximum);
|
|
9
13
|
}
|
package/utils/filter.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export const containsSearchTerm = (obj: any, searchTerm: string): boolean => {
|
|
2
|
+
if (obj == null) {
|
|
3
|
+
return false;
|
|
4
|
+
}
|
|
2
5
|
if (typeof obj === 'object') {
|
|
3
6
|
return Object.values(obj).some(value => containsSearchTerm(value, searchTerm));
|
|
4
7
|
}
|
|
@@ -12,4 +15,4 @@ export const filterItems = <T>(items: T[], filter: string): T[] => {
|
|
|
12
15
|
const searchTerm = filter.toLowerCase();
|
|
13
16
|
|
|
14
17
|
return items.filter(item => containsSearchTerm(item, searchTerm));
|
|
15
|
-
};
|
|
18
|
+
};
|
package/utils/index.ts
CHANGED
|
@@ -8,6 +8,8 @@ export * from "./icons";
|
|
|
8
8
|
export * from "./leafletMarkers"
|
|
9
9
|
export * from "./levenshtein";
|
|
10
10
|
export * from "./lexical";
|
|
11
|
+
export * from "./operations";
|
|
12
|
+
export * from "./picker";
|
|
11
13
|
export * from "./sort";
|
|
12
14
|
export * from "./statuses";
|
|
13
15
|
export * from "./time";
|
package/utils/leafletMarkers.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export const locationMarkerHtml = (icon: string, color: string) => {
|
|
1
|
+
export const locationMarkerHtml = (icon: string, color: string, label: string = '') => {
|
|
2
2
|
const iconHtml = `
|
|
3
|
-
<div style="--fs-map-location-pin-color-alpha:${color}50;--fs-map-location-pin-color: ${color}">
|
|
3
|
+
<div title="${label}" style="--fs-map-location-pin-color-alpha:${color}50;--fs-map-location-pin-color: ${color}">
|
|
4
4
|
<i class="${icon} mdi notranslate v-theme--DefaultTheme fs-icon" aria-hidden="true" style="--fs-icon-font-size: 22px;" />
|
|
5
5
|
</div>`;
|
|
6
6
|
|
|
@@ -22,8 +22,8 @@ export const gpsMarkerHtml = () => {
|
|
|
22
22
|
return iconHtml;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export const pinMarkerHtml = (color: string) => {
|
|
26
|
-
const iconHtml = `<div style="--fs-map-point-pin-color:${color}" class="fs-map-point-pin" />`;
|
|
25
|
+
export const pinMarkerHtml = (color: string, label: string = "") => {
|
|
26
|
+
const iconHtml = `<div title="${label}" style="--fs-map-point-pin-color:${color}" class="fs-map-point-pin" />`;
|
|
27
27
|
|
|
28
28
|
return iconHtml;
|
|
29
29
|
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
const MinusOperator = "-";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Splits an expression by operators while keeping unary minus signs.
|
|
5
|
+
*/
|
|
6
|
+
const splitByOperators = (expression: string): string[] => {
|
|
7
|
+
const tokens: string[] = [];
|
|
8
|
+
let current = '';
|
|
9
|
+
let expectOperand = true;
|
|
10
|
+
|
|
11
|
+
for (let i = 0; i < expression.length; i++) {
|
|
12
|
+
const char = expression[i];
|
|
13
|
+
if ('+-*/'.includes(char)) {
|
|
14
|
+
const isUnaryMinus = char === '-' && expectOperand;
|
|
15
|
+
if (isUnaryMinus) {
|
|
16
|
+
current += char;
|
|
17
|
+
expectOperand = true;
|
|
18
|
+
} else {
|
|
19
|
+
if (expectOperand) {
|
|
20
|
+
// 2 consecutive operators or operator at the start
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
if (current !== '') {
|
|
24
|
+
tokens.push(current);
|
|
25
|
+
current = '';
|
|
26
|
+
}
|
|
27
|
+
tokens.push(char);
|
|
28
|
+
expectOperand = true;
|
|
29
|
+
}
|
|
30
|
+
} else {
|
|
31
|
+
current += char;
|
|
32
|
+
expectOperand = false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (current !== '') {
|
|
36
|
+
tokens.push(current);
|
|
37
|
+
}
|
|
38
|
+
return tokens;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Matches a nested block of parenthesis
|
|
42
|
+
const parenthesisRegex = new RegExp(/\([^)(]+\)/gm);
|
|
43
|
+
|
|
44
|
+
// Match a positive decimal number
|
|
45
|
+
const decimalRegex = new RegExp(/^\d+(.\d+)?$/gm);
|
|
46
|
+
|
|
47
|
+
const validateBlock = (block: string, operands: string[] = [], variables: string[] = []) => {
|
|
48
|
+
// Remove parenthesis from the block
|
|
49
|
+
block = block.replaceAll("(", "").replaceAll(")", "");
|
|
50
|
+
|
|
51
|
+
// Split block on operators (Leave negative signs)
|
|
52
|
+
const tokens = splitByOperators(block);
|
|
53
|
+
if (tokens.length === 0) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
const components = tokens.filter(token => !'+-*/'.includes(token));
|
|
57
|
+
|
|
58
|
+
// Check if each bit is a valid operand
|
|
59
|
+
for (let i = 0; i < components.length; i++) {
|
|
60
|
+
// Remove negative sign
|
|
61
|
+
if (components[i].startsWith(MinusOperator)) {
|
|
62
|
+
components[i] = components[i].substring(1);
|
|
63
|
+
}
|
|
64
|
+
if (!operands.includes(components[i]) && !variables.includes(components[i]) && !components[i].match(decimalRegex)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export const validateOperation = (rawOperation: string, operands: string[] = [], variables: string[] = []) => {
|
|
72
|
+
// Remove spaces
|
|
73
|
+
let operation = rawOperation.replaceAll(" ", "");
|
|
74
|
+
|
|
75
|
+
// Check parenthesis
|
|
76
|
+
const parenthesis: number[] = [];
|
|
77
|
+
|
|
78
|
+
for (let i = 0; i < operation.length; i++) {
|
|
79
|
+
if (operation[i] == '(') {
|
|
80
|
+
parenthesis.push(i);
|
|
81
|
+
}
|
|
82
|
+
else if (operation[i] == ')') {
|
|
83
|
+
if (parenthesis.length > 0) {
|
|
84
|
+
if (i == parenthesis.pop()! + 1) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (parenthesis.length > 0) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Check each block between parenthesis
|
|
98
|
+
let match = operation.match(parenthesisRegex);
|
|
99
|
+
|
|
100
|
+
while (match?.[0]) {
|
|
101
|
+
if (!validateBlock(match[0], operands, variables)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
operation = operation.replace(match[0], "1");
|
|
105
|
+
match = operation.match(parenthesisRegex);
|
|
106
|
+
}
|
|
107
|
+
return validateBlock(operation, operands, variables);
|
|
108
|
+
}
|