@itfin/components 1.4.36 → 1.5.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.
- package/package.json +17 -20
- package/src/ITFSettings.js +6 -0
- package/src/assets/scss/_css_variables.scss +2 -7
- package/src/assets/scss/_dark-theme.scss +2 -12
- package/src/assets/scss/_variables.scss +34 -9
- package/src/assets/scss/components/_button.scss +147 -10
- package/src/assets/scss/components/_checkbox.scss +9 -0
- package/src/assets/scss/components/_datepicker.scss +3 -3
- package/src/assets/scss/components/_pagination.scss +4 -1
- package/src/assets/scss/components/_popover.scss +22 -0
- package/src/assets/scss/components/_segmeneted-control.scss +19 -8
- package/src/assets/scss/components/_select.scss +6 -8
- package/src/assets/scss/components/_text-field.scss +27 -11
- package/src/assets/scss/components/select/_dropdown-menu.scss +1 -0
- package/src/assets/scss/components/select/_dropdown-toggle.scss +0 -1
- package/src/assets/scss/directives/tooltip.scss +10 -5
- package/src/assets/scss/main.scss +48 -0
- package/src/components/alert/AlertBanner.vue +75 -0
- package/src/components/app/App.vue +6 -3
- package/src/components/button/Button.vue +3 -1
- package/src/components/button/NativeButton.js +4 -0
- package/src/components/button/index.stories.js +2 -2
- package/src/components/checkbox/Checkbox.vue +2 -1
- package/src/components/checkbox/RadioBox.vue +13 -7
- package/src/components/copyToClipboard/CopyToClipboard.vue +4 -1
- package/src/components/customize/PropertiesList.vue +0 -2
- package/src/components/customize/PropertiesPopupMenu.vue +1 -1
- package/src/components/customize/PropertyItem.vue +6 -24
- package/src/components/datepicker/DatePicker.vue +3 -1
- package/src/components/datepicker/DatePickerInline.vue +2 -2
- package/src/components/datepicker/DateRangePickerInline.vue +6 -1
- package/src/components/dropdown/Dropdown.vue +1 -1
- package/src/components/dropdown/DropdownMenu.vue +1 -1
- package/src/components/editable/EditButton.vue +1 -1
- package/src/components/filter/FilterBadge.vue +20 -1
- package/src/components/filter/FilterFacetsList.vue +67 -13
- package/src/components/filter/FilterPanel.vue +8 -4
- package/src/components/filter/NewFilter.vue +305 -0
- package/src/components/form/Label.vue +5 -5
- package/src/components/icon/components/nomi-ai-alt.vue +5 -0
- package/src/components/icon/components/nomi-arrow-right.vue +4 -0
- package/src/components/icon/components/nomi-bell.vue +5 -0
- package/src/components/icon/components/nomi-calendar-payment.vue +10 -0
- package/src/components/icon/components/nomi-card-plus.vue +1 -0
- package/src/components/icon/components/nomi-cash-provider.vue +9 -0
- package/src/components/icon/components/nomi-cash-repeat.vue +6 -0
- package/src/components/icon/components/nomi-category-edit.vue +5 -0
- package/src/components/icon/components/nomi-chavron-up.vue +4 -0
- package/src/components/icon/components/nomi-chavron_down.vue +4 -0
- package/src/components/icon/components/nomi-chavron_up.vue +4 -0
- package/src/components/icon/components/nomi-chevron-up.vue +4 -0
- package/src/components/icon/components/nomi-exit-right.vue +4 -0
- package/src/components/icon/components/nomi-help.vue +2 -3
- package/src/components/icon/components/nomi-history.vue +7 -0
- package/src/components/icon/components/nomi-lock.vue +1 -1
- package/src/components/icon/components/nomi-pen-alt.vue +4 -0
- package/src/components/icon/components/nomi-project.vue +2 -2
- package/src/components/icon/components/nomi-refresh-off.vue +4 -0
- package/src/components/icon/components/nomi-refresh.vue +4 -0
- package/src/components/icon/components/nomi-scissors.vue +1 -1
- package/src/components/icon/components/nomi-start.vue +28 -0
- package/src/components/icon/components/nomi-table-view.vue +1 -4
- package/src/components/icon/components/nomi-transactions-delete.vue +5 -0
- package/src/components/icon/components/nomi-type-array.vue +6 -0
- package/src/components/icon/components/nomi-type-boolean.vue +5 -0
- package/src/components/icon/components/nomi-type-date.vue +4 -0
- package/src/components/icon/components/nomi-type-null.vue +4 -0
- package/src/components/icon/components/nomi-type-number.vue +4 -0
- package/src/components/icon/components/nomi-type-object.vue +4 -0
- package/src/components/icon/components/nomi-type-string.vue +4 -0
- package/src/components/icon/components/nomi-unarchive.vue +17 -0
- package/src/components/icon/components/nomi-unlink.vue +10 -0
- package/src/components/icon/components/nomi-user.vue +3 -3
- package/src/components/icon/components/nomi-warning-triangle.vue +6 -0
- package/src/components/icon/components/nomi-warning_triangle_filled.vue +6 -0
- package/src/components/icon/convert-icons.js +3 -0
- package/src/components/icon/icons.js +390 -312
- package/src/components/icon/new-icons/ai-alt.svg +4 -0
- package/src/components/icon/new-icons/arrow-right-alt.svg +3 -0
- package/src/components/icon/new-icons/arrow-right.svg +3 -0
- package/src/components/icon/new-icons/arrow_left.svg +3 -0
- package/src/components/icon/new-icons/automation.svg +4 -0
- package/src/components/icon/new-icons/balance.svg +3 -0
- package/src/components/icon/new-icons/balance_turnover.svg +4 -0
- package/src/components/icon/new-icons/bar-horizontal.svg +6 -0
- package/src/components/icon/new-icons/bell.svg +4 -0
- package/src/components/icon/new-icons/calendar-payment.svg +9 -0
- package/src/components/icon/new-icons/card-plus.svg +1 -0
- package/src/components/icon/new-icons/cash-provider.svg +8 -0
- package/src/components/icon/new-icons/cash-repeat.svg +5 -0
- package/src/components/icon/new-icons/cash.svg +3 -0
- package/src/components/icon/new-icons/cashflow.svg +3 -0
- package/src/components/icon/new-icons/category-edit.svg +4 -0
- package/src/components/icon/new-icons/category.svg +4 -0
- package/src/components/icon/new-icons/category_alt.svg +3 -0
- package/src/components/icon/new-icons/chart-bars.svg +5 -0
- package/src/components/icon/new-icons/chart-donut.svg +3 -0
- package/src/components/icon/new-icons/chart-funnel.svg +5 -0
- package/src/components/icon/new-icons/chart-kpi.svg +7 -0
- package/src/components/icon/new-icons/chart-line.svg +4 -0
- package/src/components/icon/new-icons/chart-lines.svg +5 -0
- package/src/components/icon/new-icons/check-alt.svg +3 -0
- package/src/components/icon/new-icons/check.svg +3 -0
- package/src/components/icon/new-icons/chevron-down.svg +3 -0
- package/src/components/icon/new-icons/chevron-left.svg +3 -0
- package/src/components/icon/new-icons/chevron-right.svg +3 -0
- package/src/components/icon/new-icons/chevron-up.svg +3 -0
- package/src/components/icon/new-icons/collapse.svg +6 -0
- package/src/components/icon/new-icons/control-panel.svg +7 -0
- package/src/components/icon/new-icons/credit.svg +3 -0
- package/src/components/icon/new-icons/currencies.svg +3 -0
- package/src/components/icon/new-icons/debt.svg +3 -0
- package/src/components/icon/new-icons/demo.svg +6 -0
- package/src/components/icon/new-icons/dev.svg +3 -0
- package/src/components/icon/new-icons/dots.svg +5 -0
- package/src/components/icon/new-icons/duplicate.svg +4 -0
- package/src/components/icon/new-icons/exit-right.svg +3 -0
- package/src/components/icon/new-icons/export.svg +3 -0
- package/src/components/icon/new-icons/file.svg +3 -0
- package/src/components/icon/new-icons/folder.svg +3 -0
- package/src/components/icon/new-icons/goods-turnover.svg +3 -0
- package/src/components/icon/new-icons/goods.svg +4 -0
- package/src/components/icon/new-icons/help-alt.svg +3 -0
- package/src/components/icon/new-icons/help.svg +2 -3
- package/src/components/icon/new-icons/history.svg +6 -0
- package/src/components/icon/new-icons/integration.svg +3 -0
- package/src/components/icon/new-icons/link.svg +5 -0
- package/src/components/icon/new-icons/lock.svg +1 -1
- package/src/components/icon/new-icons/menu.svg +5 -0
- package/src/components/icon/new-icons/minus.svg +3 -0
- package/src/components/icon/new-icons/payment_calendar.svg +3 -0
- package/src/components/icon/new-icons/pc.svg +3 -0
- package/src/components/icon/new-icons/pen-alt.svg +3 -0
- package/src/components/icon/new-icons/planFact.svg +4 -0
- package/src/components/icon/new-icons/pnl.svg +7 -0
- package/src/components/icon/new-icons/project.svg +2 -2
- package/src/components/icon/new-icons/project_alt.svg +3 -0
- package/src/components/icon/new-icons/project_alt2.svg +3 -0
- package/src/components/icon/new-icons/promo.svg +3 -0
- package/src/components/icon/new-icons/refresh-off.svg +3 -0
- package/src/components/icon/new-icons/refresh.svg +3 -0
- package/src/components/icon/new-icons/scissors.svg +1 -1
- package/src/components/icon/new-icons/segment.svg +3 -0
- package/src/components/icon/new-icons/start.svg +27 -0
- package/src/components/icon/new-icons/strongbox.svg +3 -0
- package/src/components/icon/new-icons/subscription.svg +3 -0
- package/src/components/icon/new-icons/table-view.svg +1 -4
- package/src/components/icon/new-icons/time.svg +3 -0
- package/src/components/icon/new-icons/transactions_alt.svg +6 -0
- package/src/components/icon/new-icons/transactions_delete.svg +4 -0
- package/src/components/icon/new-icons/type-array.svg +5 -0
- package/src/components/icon/new-icons/type-boolean.svg +4 -0
- package/src/components/icon/new-icons/type-date.svg +3 -0
- package/src/components/icon/new-icons/type-null.svg +3 -0
- package/src/components/icon/new-icons/type-number.svg +3 -0
- package/src/components/icon/new-icons/type-object.svg +3 -0
- package/src/components/icon/new-icons/type-string.svg +3 -0
- package/src/components/icon/new-icons/types.svg +6 -0
- package/src/components/icon/new-icons/unarchive.svg +16 -0
- package/src/components/icon/new-icons/unlink.svg +9 -0
- package/src/components/icon/new-icons/user.svg +3 -3
- package/src/components/icon/new-icons/user_plus.svg +10 -0
- package/src/components/icon/new-icons/warehouse.svg +3 -0
- package/src/components/icon/new-icons/warning_triangle.svg +5 -0
- package/src/components/icon/new-icons/warning_triangle_filled.svg +5 -0
- package/src/components/kanban/BoardCard.vue +1 -1
- package/src/components/kanban/BoardCardTimer.vue +1 -1
- package/src/components/modal/DeleteConfirmModal.vue +10 -6
- package/src/components/modal/ItemEditor.vue +1 -1
- package/src/components/modal/Modal.vue +1 -1
- package/src/components/overlay/SensitiveOverlay.vue +2 -4
- package/src/components/panels/Panel.vue +110 -23
- package/src/components/panels/PanelItemEdit.vue +8 -6
- package/src/components/panels/PanelList.vue +163 -40
- package/src/components/panels/helpers.ts +29 -11
- package/src/components/popover/Popover.vue +105 -22
- package/src/components/segmented-control/SegmentedControl.vue +9 -3
- package/src/components/sortable/draggable.js +1 -1
- package/src/components/table/Table2.vue +68 -67
- package/src/components/table/TableBody.vue +17 -22
- package/src/components/table/TableGroup.vue +40 -24
- package/src/components/table/TableHeader.vue +86 -81
- package/src/components/table/TableRowToggle.vue +1 -9
- package/src/components/table/TableRows.vue +49 -55
- package/src/components/table/mobile.js +4 -0
- package/src/components/table/table2.scss +34 -15
- package/src/components/text-field/MoneyField.vue +10 -4
- package/src/components/text-field/TextField.vue +17 -8
- package/src/components/tree/TreeEditor.vue +3 -2
- package/src/components/view/View.vue +73 -208
- package/src/directives/appendToBody.js +1 -0
- package/src/helpers/validators.js +9 -35
- package/src/helpers/validators.spec.js +11 -48
- package/src/locales/en.js +4 -6
- package/src/locales/pl.js +158 -0
- package/src/locales/uk.js +6 -7
- package/src/components/icon/components/nomi-calendar-view.vue +0 -4
- package/src/components/icon/components/nomi-kanban-view.vue +0 -6
- package/src/components/icon/components/nomi-list-view.vue +0 -7
- package/src/components/icon/components/nomi-table-config.vue +0 -9
- package/src/components/icon/new-icons/calendar-view.svg +0 -3
- package/src/components/icon/new-icons/kanban-view.svg +0 -5
- package/src/components/icon/new-icons/list-view.svg +0 -6
- package/src/components/icon/new-icons/table-config.svg +0 -8
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
|
|
3
|
-
<div class="itf-text-field input-group" :class="{ '
|
|
3
|
+
<div class="itf-text-field input-group form-control p-0" :class="{ 'is-invalid': isInvalid(), 'is-valid': isSuccess() }">
|
|
4
4
|
<slot name="addon">
|
|
5
|
-
<div class="
|
|
6
|
-
<itf-icon :name="prependIcon"/>
|
|
5
|
+
<div class="input-group-text prepend text-muted" v-if="prependIcon">
|
|
6
|
+
<itf-icon :size="small ? 18 : 20" :name="prependIcon"/>
|
|
7
7
|
</div>
|
|
8
8
|
</slot>
|
|
9
9
|
|
|
10
10
|
<input
|
|
11
|
+
:name="`text-field-${_uid}`"
|
|
11
12
|
ref="input"
|
|
12
13
|
autocomplete="off"
|
|
13
14
|
:placeholder="placeholder"
|
|
14
|
-
:class="{ '
|
|
15
|
+
:class="{ 'form-control-sm': small }"
|
|
15
16
|
class="itf-text-field__input form-control"
|
|
16
17
|
:type="type"
|
|
17
18
|
:value="value"
|
|
@@ -24,12 +25,16 @@
|
|
|
24
25
|
@blur="$emit('blur', $event)"
|
|
25
26
|
@focus="$emit('focus', $event)"
|
|
26
27
|
@change="$emit('change', $event.target.value)"
|
|
28
|
+
:maxlength="maxlength"
|
|
27
29
|
:min="min"
|
|
28
30
|
:max="max"
|
|
29
31
|
:step="step"
|
|
30
32
|
/>
|
|
33
|
+
<div class="input-group-text append text-muted" v-if="postfix">
|
|
34
|
+
{{ postfix }}
|
|
35
|
+
</div>
|
|
31
36
|
|
|
32
|
-
<
|
|
37
|
+
<template v-if="clearable && value">
|
|
33
38
|
<slot name="clear">
|
|
34
39
|
<itf-button
|
|
35
40
|
icon
|
|
@@ -39,7 +44,7 @@
|
|
|
39
44
|
<itf-icon name="close" />
|
|
40
45
|
</itf-button>
|
|
41
46
|
</slot>
|
|
42
|
-
</
|
|
47
|
+
</template>
|
|
43
48
|
</div>
|
|
44
49
|
|
|
45
50
|
</template>
|
|
@@ -64,10 +69,14 @@ class itfTextField extends Vue {
|
|
|
64
69
|
@Prop() step;
|
|
65
70
|
@Prop() min;
|
|
66
71
|
@Prop() max;
|
|
72
|
+
@Prop() maxlength;
|
|
73
|
+
@Prop() postfix;
|
|
67
74
|
@Prop(Boolean) clearable;
|
|
68
75
|
@Prop(Boolean) disabled;
|
|
69
76
|
@Prop(Boolean) readonly;
|
|
70
77
|
@Prop(Boolean) small;
|
|
78
|
+
@Prop({ type: Boolean, default: undefined }) invalid;
|
|
79
|
+
@Prop({ type: Boolean, default: undefined }) valid;
|
|
71
80
|
@Prop({ type: String, default: 'text' }) type;
|
|
72
81
|
@Prop({ type: [Number, String], default: 0 }) delayInput;
|
|
73
82
|
|
|
@@ -78,11 +87,11 @@ class itfTextField extends Vue {
|
|
|
78
87
|
}
|
|
79
88
|
|
|
80
89
|
isInvalid() {
|
|
81
|
-
return this.itemLabel && this.itemLabel.isHasError();
|
|
90
|
+
return typeof this.invalid !== 'undefined' ? this.invalid : (this.itemLabel && this.itemLabel.isHasError());
|
|
82
91
|
}
|
|
83
92
|
|
|
84
93
|
isSuccess() {
|
|
85
|
-
return this.itemLabel && this.itemLabel.isHasSuccess();
|
|
94
|
+
return typeof this.valid !== 'undefined' ? this.valid : (this.itemLabel && this.itemLabel.isHasSuccess());
|
|
86
95
|
}
|
|
87
96
|
|
|
88
97
|
insertTextToCurrentPosition(text) {
|
|
@@ -25,10 +25,11 @@
|
|
|
25
25
|
@keyup.enter="(e)=>{$emit('click',{event:e,ele:e.target,node,knode})}"
|
|
26
26
|
@click="(e)=>{$emit('click',{event:e,ele:e.target,node,knode})}"
|
|
27
27
|
>
|
|
28
|
-
<div v-if="node.level >= toggleStartLevel" class="itf-tree-editor_node_toggle
|
|
28
|
+
<div v-if="node.level >= toggleStartLevel" class="itf-tree-editor_node_toggle">
|
|
29
29
|
<itf-button
|
|
30
|
-
v-if="autoToggleTree && node.level >= toggleStartLevel && node
|
|
30
|
+
v-if="autoToggleTree && node.level >= toggleStartLevel && node[itemChildren] && node[itemChildren].length > 0"
|
|
31
31
|
small
|
|
32
|
+
icon
|
|
32
33
|
@click.stop="toggleNode($event, node, knode)"
|
|
33
34
|
>
|
|
34
35
|
<itf-icon v-if="isNodeToggled(node)" name="plus" size="24" />
|
|
@@ -4,25 +4,26 @@
|
|
|
4
4
|
<itf-filter-panel
|
|
5
5
|
:search-placeholder="searchPlaceholder"
|
|
6
6
|
search
|
|
7
|
-
|
|
7
|
+
:visible="!noFilters"
|
|
8
|
+
:filters-only="filtersOnly"
|
|
9
|
+
ref="filters"
|
|
10
|
+
:mini="panel.isMultiple()"
|
|
8
11
|
class="py-2 px-3"
|
|
9
|
-
:static-filters="filters"
|
|
10
12
|
:endpoint="filtersEndpoint"
|
|
11
13
|
:panel="panel"
|
|
12
14
|
v-model="filter"
|
|
13
15
|
@loaded="onFilterSet($event, true)"
|
|
14
16
|
@change="onFilterSet($event, false)"
|
|
15
|
-
@set-table-schema="setTableSchema"
|
|
16
17
|
>
|
|
17
18
|
<template #after-filter-btn>
|
|
18
|
-
<itf-dropdown v-if="$refs.table &&
|
|
19
|
+
<itf-dropdown v-if="$refs.table && schema" shadow append-to-context :button-options="{ default: true, icon: true }" class="h-100" autoclose="outside">
|
|
19
20
|
<template #button>
|
|
20
|
-
<itf-icon new name="table-
|
|
21
|
+
<itf-icon new name="table-view" />
|
|
21
22
|
</template>
|
|
22
23
|
<div class="dropdown-header">
|
|
23
24
|
{{ $t('components.table.columns') }}
|
|
24
25
|
</div>
|
|
25
|
-
<a v-for="(property, n) of
|
|
26
|
+
<a v-for="(property, n) of schema.properties" :key="n" href="" @click.stop.prevent="$refs.table.toggleVisibility(property.property)" class="dropdown-item justify-content-between d-flex gap-3">
|
|
26
27
|
<div class="d-flex align-items-center gap-1">
|
|
27
28
|
<itf-icon v-if="property.icon" :size="24" new :name="property.icon" />
|
|
28
29
|
{{getTitle(property.title)}}
|
|
@@ -41,101 +42,61 @@
|
|
|
41
42
|
</div>
|
|
42
43
|
</a>
|
|
43
44
|
</itf-dropdown>
|
|
44
|
-
<itf-dropdown v-if="downloadEndpoint" shadow append-to-context :button-options="{ default: true, small: true }" class="h-100" autoclose="outside">
|
|
45
|
-
<template #button>
|
|
46
|
-
<itf-icon name="download"/>
|
|
47
|
-
{{ $t('export') }}
|
|
48
|
-
</template>
|
|
49
|
-
<a v-for="(item, n) in getDownloadLinks()" target="_blank" :key="n" :href="item.link" class="dropdown-item">
|
|
50
|
-
{{item.title}}
|
|
51
|
-
</a>
|
|
52
|
-
</itf-dropdown>
|
|
53
|
-
|
|
54
|
-
<slot name="before-tabs"></slot>
|
|
55
|
-
|
|
56
|
-
<itf-segmented-control
|
|
57
|
-
v-if="tabs.length > 1"
|
|
58
|
-
class="small"
|
|
59
|
-
v-model="currentTab"
|
|
60
|
-
item-key="value"
|
|
61
|
-
:items="tabs"
|
|
62
|
-
>
|
|
63
|
-
<template #item="{ item }">
|
|
64
|
-
<div class="d-flex align-items-center">
|
|
65
|
-
<itf-icon class="text-muted" new :name="item.icon" />
|
|
66
|
-
{{item.text}}
|
|
67
|
-
</div>
|
|
68
|
-
</template>
|
|
69
|
-
</itf-segmented-control>
|
|
70
45
|
</template>
|
|
71
46
|
</itf-filter-panel>
|
|
72
47
|
|
|
73
|
-
<div
|
|
74
|
-
<div class="position-
|
|
75
|
-
|
|
48
|
+
<div class="flex-grow-1 px-3 d-flex flex-column">
|
|
49
|
+
<div class="position-relative flex-grow-1">
|
|
50
|
+
<itf-table
|
|
51
|
+
ref="table"
|
|
52
|
+
style="--shadow-area-width: 0px;"
|
|
53
|
+
absolute
|
|
54
|
+
striped
|
|
55
|
+
clickable
|
|
56
|
+
column-sorting
|
|
57
|
+
column-resizing
|
|
58
|
+
:indicator-type="indicatorType"
|
|
59
|
+
class="permanent-checkboxes"
|
|
60
|
+
:state-name="stateName"
|
|
61
|
+
id-property="id"
|
|
62
|
+
:rows="preparedItems"
|
|
63
|
+
:schema="schema"
|
|
64
|
+
:sorting="sorting"
|
|
65
|
+
:active="activeIds"
|
|
66
|
+
:show-actions="showActions"
|
|
67
|
+
v-model="selectedIds"
|
|
68
|
+
@row-click="$emit('open', $event)"
|
|
69
|
+
@update:sorting="updateSorting($event)"
|
|
70
|
+
>
|
|
71
|
+
<template v-for="(_, name) in $slots" #[name]="slotData">
|
|
72
|
+
<slot :name="name" v-bind="slotData || {}"/>
|
|
73
|
+
</template>
|
|
74
|
+
<template v-for="(_, name) in $scopedSlots" #[name]="slotData">
|
|
75
|
+
<slot :name="name" v-bind="slotData || {}"/>
|
|
76
|
+
</template>
|
|
77
|
+
</itf-table>
|
|
76
78
|
</div>
|
|
77
79
|
</div>
|
|
78
|
-
<slot v-else-if="currentTab === 'board'" name="kanban-view"></slot>
|
|
79
|
-
<slot v-else-if="currentTab === 'calendar'" name="calendar-view"></slot>
|
|
80
|
-
<slot v-else name="table-view">
|
|
81
|
-
<div class="flex-grow-1 px-3 d-flex flex-column">
|
|
82
|
-
<div class="position-relative flex-grow-1">
|
|
83
|
-
<itf-table
|
|
84
|
-
ref="table"
|
|
85
|
-
style="--shadow-area-width: 0px;"
|
|
86
|
-
absolute
|
|
87
|
-
striped
|
|
88
|
-
clickable
|
|
89
|
-
column-sorting
|
|
90
|
-
column-resizing
|
|
91
|
-
:indicator-type="indicatorType"
|
|
92
|
-
class="permanent-checkboxes"
|
|
93
|
-
:state-name="stateName"
|
|
94
|
-
id-property="id"
|
|
95
|
-
:sort-as-string="sortAsString"
|
|
96
|
-
:rows="items"
|
|
97
|
-
:group-by="groupBy"
|
|
98
|
-
:schema="tableSchema"
|
|
99
|
-
:sorting.sync="sorting"
|
|
100
|
-
:active="activeIds"
|
|
101
|
-
:no-select-all="noSelectAll"
|
|
102
|
-
:show-actions="showActions"
|
|
103
|
-
:indicator-width="indicatorWidth"
|
|
104
|
-
v-model="selectedIds"
|
|
105
|
-
@row-click="$emit('open', $event)"
|
|
106
|
-
@update:sorting="updateSorting($event)"
|
|
107
|
-
>
|
|
108
|
-
<template v-for="(_, name) in $slots" #[name]="slotData">
|
|
109
|
-
<slot :name="name" v-bind="slotData || {}"/>
|
|
110
|
-
</template>
|
|
111
|
-
<template v-for="(_, name) in $scopedSlots" #[name]="slotData">
|
|
112
|
-
<slot :name="name" v-bind="slotData || {}"/>
|
|
113
|
-
</template>
|
|
114
|
-
</itf-table>
|
|
115
|
-
</div>
|
|
116
|
-
</div>
|
|
117
|
-
</slot>
|
|
118
80
|
|
|
119
81
|
<itf-pagination
|
|
120
82
|
class="my-2 px-3"
|
|
121
|
-
v-if="showPagination"
|
|
122
83
|
show-size
|
|
123
84
|
:size="size"
|
|
124
|
-
:items="
|
|
85
|
+
:items="preparedItems"
|
|
125
86
|
:pages="countPages"
|
|
126
87
|
:value="page"
|
|
127
88
|
@input="updatePage($event)"
|
|
128
89
|
@per-page="updateSizePerPage($event)"
|
|
129
90
|
>
|
|
130
91
|
<template #center>
|
|
131
|
-
<slot name="pagination-center"
|
|
92
|
+
<slot name="pagination-center" />
|
|
132
93
|
</template>
|
|
133
94
|
</itf-pagination>
|
|
134
95
|
</div>
|
|
135
96
|
|
|
136
97
|
</template>
|
|
137
98
|
<script>
|
|
138
|
-
import {Vue, ModelSync, Component, Prop, Inject
|
|
99
|
+
import { Vue, ModelSync, Component, Prop, Inject } from 'vue-property-decorator';
|
|
139
100
|
import loading from '../../directives/loading';
|
|
140
101
|
import itfTable from '../table/Table2.vue';
|
|
141
102
|
import itfFilterPanel from '../filter/FilterPanel.vue';
|
|
@@ -143,16 +104,11 @@ import itfPagination from '../pagination/Pagination2.vue';
|
|
|
143
104
|
import itfTableBody from "../table/TableBody.vue";
|
|
144
105
|
import itfIcon from "../icon/Icon.vue";
|
|
145
106
|
import itfDropdown from "../dropdown/Dropdown.vue";
|
|
146
|
-
import itfSegmentedControl from '../segmented-control/SegmentedControl.vue';
|
|
147
|
-
import itfButton from '@itfin/components/src/components/button/Button.vue';
|
|
148
107
|
|
|
149
108
|
export default @Component({
|
|
150
109
|
name: 'itfView',
|
|
151
110
|
components: {
|
|
152
|
-
|
|
153
|
-
itfSegmentedControl,
|
|
154
|
-
itfDropdown,
|
|
155
|
-
itfIcon,
|
|
111
|
+
itfDropdown, itfIcon,
|
|
156
112
|
itfPagination,
|
|
157
113
|
itfFilterPanel,
|
|
158
114
|
itfTableBody,
|
|
@@ -167,32 +123,24 @@ class itfView extends Vue {
|
|
|
167
123
|
@ModelSync('value', 'input') selectedIds;
|
|
168
124
|
|
|
169
125
|
@Prop({ type: Boolean }) loading;
|
|
126
|
+
@Prop({ type: Boolean }) filtersOnly;
|
|
127
|
+
@Prop({ type: Boolean }) noFilters;
|
|
170
128
|
@Prop({ type: Array }) filters;
|
|
171
|
-
@Prop({ type: Object }) schema;
|
|
129
|
+
@Prop({ type: Object, required: true }) schema;
|
|
130
|
+
// @Prop({ default: 20 }) size;
|
|
131
|
+
// @Prop({ default: 1 }) page;
|
|
172
132
|
@Prop(String) defaultSorting;
|
|
173
133
|
@Prop(String) endpoint;
|
|
174
134
|
@Prop(String) filtersEndpoint;
|
|
175
135
|
@Prop(String) itemsKey;
|
|
176
|
-
@Prop({ type: String, default: null }) groupBy;
|
|
177
|
-
@Prop({ type: String, default: null }) downloadEndpoint; // префікс апі для завантаження
|
|
178
|
-
@Prop({ type: String, default: 'totals' }) totalsKey;
|
|
179
136
|
@Prop(String) panelKey;
|
|
180
137
|
@Prop(String) stateName;
|
|
181
138
|
@Prop({ type: String, default: 'checkbox' }) indicatorType;
|
|
182
|
-
@Prop({ type: String, default: 'list' }) tab;
|
|
183
139
|
@Prop({ type: String, default () { return this.$t('components.table.search'); } }) searchPlaceholder;
|
|
184
140
|
@Prop() panel;
|
|
141
|
+
@Prop() hardFilter; // встановлює жорсткий фільтр, наприклад, треба завжди показувати лише по контрагенту
|
|
185
142
|
@Prop(Boolean) showActions;
|
|
186
|
-
@Prop({ type:
|
|
187
|
-
@Prop(Boolean) listViewEnabled;
|
|
188
|
-
@Prop(Boolean) kanbanViewEnabled;
|
|
189
|
-
@Prop(Boolean) calendarViewEnabled;
|
|
190
|
-
@Prop(Boolean) noSelectAll;
|
|
191
|
-
@Prop({ type: Boolean, default: true }) tableViewEnabled;
|
|
192
|
-
@Prop(Boolean) sortAsString;
|
|
193
|
-
@Prop(Boolean) oldFormat;
|
|
194
|
-
@Prop({ default: 45 }) indicatorWidth;
|
|
195
|
-
@Prop({type: Function, default: null }) onSplitSlectedIds // якщо потрібно розділяти вибрані рядки в таблиці на дві групи
|
|
143
|
+
@Prop({ type: Array, default: () => [] }) disabledIds;
|
|
196
144
|
|
|
197
145
|
page = 1;
|
|
198
146
|
total = 0;
|
|
@@ -202,74 +150,10 @@ class itfView extends Vue {
|
|
|
202
150
|
filter = {};
|
|
203
151
|
loadingData = false;
|
|
204
152
|
activeIds = [];
|
|
205
|
-
tableColumns = null;
|
|
206
|
-
totals = null;
|
|
207
|
-
|
|
208
|
-
@Watch('selectedIds', { deep: true, immediate: true })
|
|
209
|
-
updateSelectedIds() {
|
|
210
|
-
if(this.onSplitSlectedIds && this.items.length && this.selectedIds.length) {
|
|
211
|
-
this.onSplitSlectedIds(this.selectedIds, this.items);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
getDownloadLinks() {
|
|
216
|
-
const state = this.$refs.table ? this.$refs.table.getTableState() : null;
|
|
217
|
-
const filter = { ...this.filter };
|
|
218
|
-
const sorting = this.sorting;
|
|
219
|
-
const filterableColumnsNames = (state?.columns ?? []).filter(column => column.visible).map(column => column.property);
|
|
220
|
-
|
|
221
|
-
const filterWithValue = Object.fromEntries(Object.entries(filter).filter(([_, value]) => typeof value !== 'undefined'));
|
|
222
|
-
const params = {
|
|
223
|
-
...filterWithValue,
|
|
224
|
-
sort: sorting
|
|
225
|
-
};
|
|
226
|
-
if (filterableColumnsNames.length) {
|
|
227
|
-
params.columns = filterableColumnsNames.join(',')
|
|
228
|
-
}
|
|
229
|
-
const xlsQueryParams = new URLSearchParams({ ...params, format: 'xlsx' }).toString();
|
|
230
|
-
const csvQueryParams = new URLSearchParams({ ...params, format: 'csv' }).toString();
|
|
231
|
-
return [
|
|
232
|
-
{ title: 'Excel (xlsx)', link: `${this.downloadEndpoint}?${xlsQueryParams}` },
|
|
233
|
-
{ title: 'Plain text (csv)', link: `${this.downloadEndpoint}?${csvQueryParams}` },
|
|
234
|
-
];
|
|
235
|
-
}
|
|
236
153
|
|
|
237
|
-
get
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
set currentTab(val) {
|
|
242
|
-
this.$emit('update:tab', val);
|
|
243
|
-
this.setPanelPayload({ tab: val });
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
get tabs() {
|
|
247
|
-
const views = [];
|
|
248
|
-
if (this.listViewEnabled) {
|
|
249
|
-
views.push({ value: 'list', text: this.$t('list'), icon: 'list-view' });
|
|
250
|
-
}
|
|
251
|
-
if (this.kanbanViewEnabled) {
|
|
252
|
-
views.push({ value: 'board', text: this.$t('board'), icon: 'kanban-view' });
|
|
253
|
-
}
|
|
254
|
-
if (this.calendarViewEnabled) {
|
|
255
|
-
views.push({ value: 'calendar', text: this.$t('calendar'), icon: 'calendar-view' });
|
|
256
|
-
}
|
|
257
|
-
if (this.tableViewEnabled) {
|
|
258
|
-
views.push({ value: 'table', text: this.$t('table'), icon: 'table-view' });
|
|
259
|
-
}
|
|
260
|
-
return views;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
get tableSchema() {
|
|
264
|
-
if (this.tableColumns) {
|
|
265
|
-
return {
|
|
266
|
-
properties: this.tableColumns
|
|
267
|
-
}
|
|
268
|
-
} else if (this.schema) {
|
|
269
|
-
return this.schema
|
|
270
|
-
} else {
|
|
271
|
-
return {}
|
|
272
|
-
}
|
|
154
|
+
get preparedItems() {
|
|
155
|
+
const disabledIdsSet = new Set(this.disabledIds);
|
|
156
|
+
return this.items.map(item => ({ ...item, isDisabled: disabledIdsSet.has(item.id) }));
|
|
273
157
|
}
|
|
274
158
|
|
|
275
159
|
created() {
|
|
@@ -291,42 +175,35 @@ class itfView extends Vue {
|
|
|
291
175
|
}
|
|
292
176
|
}
|
|
293
177
|
|
|
294
|
-
async loadData() {
|
|
178
|
+
async loadData(reloadFilters = false) {
|
|
295
179
|
if (!this.endpoint) {
|
|
296
180
|
return;
|
|
297
181
|
}
|
|
182
|
+
if (reloadFilters) {
|
|
183
|
+
this.loadFilters();
|
|
184
|
+
}
|
|
298
185
|
this.$emit('load', this.filter);
|
|
299
186
|
this.loadingData = true;
|
|
300
187
|
await this.$try(async () => {
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
filter = Object.keys(filter).reduce((acc, key) => {
|
|
304
|
-
acc[`filter[${key}]`] = filter[key];
|
|
305
|
-
return acc;
|
|
306
|
-
}, {})
|
|
307
|
-
}
|
|
308
|
-
const { data, headers } = await this.$axios.get(this.endpoint, {
|
|
188
|
+
const res = await this.$axios.$get(this.endpoint, {
|
|
189
|
+
preventRaceCondition: true,
|
|
309
190
|
params: {
|
|
310
|
-
...filter,
|
|
191
|
+
...Object.assign(this.filter ?? {}, this.hardFilter ?? {}),
|
|
311
192
|
page: this.page,
|
|
312
193
|
size: this.size,
|
|
313
194
|
sort: this.sorting
|
|
314
195
|
}
|
|
315
196
|
});
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
this.total = data.meta.total;
|
|
326
|
-
this.size = data.meta.size;
|
|
327
|
-
}
|
|
197
|
+
this.selectedIds = [];
|
|
198
|
+
this.items = res[this.itemsKey];
|
|
199
|
+
this.page = res.meta.page;
|
|
200
|
+
this.total = res.meta.total;
|
|
201
|
+
this.size = res.meta.size;
|
|
202
|
+
this.$emit('update:items', this.items);
|
|
203
|
+
this.loadingData = false;
|
|
204
|
+
}, () => {
|
|
205
|
+
this.loadingData = false;
|
|
328
206
|
});
|
|
329
|
-
this.loadingData = false;
|
|
330
207
|
this.$emit('loaded', this.filter);
|
|
331
208
|
}
|
|
332
209
|
|
|
@@ -349,16 +226,14 @@ class itfView extends Vue {
|
|
|
349
226
|
|
|
350
227
|
updatePage (val) {
|
|
351
228
|
this.page = val;
|
|
352
|
-
this.
|
|
353
|
-
this.setPanelPayload({ page: val });
|
|
229
|
+
this.setPanelPayload({ page: val === 1 ? null : val });
|
|
354
230
|
this.loadData();
|
|
355
231
|
}
|
|
356
232
|
|
|
357
233
|
updateSizePerPage (val) {
|
|
358
234
|
this.page = 1;
|
|
359
235
|
this.size = val;
|
|
360
|
-
this.
|
|
361
|
-
this.setPanelPayload({ page: 1, size: val });
|
|
236
|
+
this.setPanelPayload({ page: null, size: val });
|
|
362
237
|
this.loadData();
|
|
363
238
|
localStorage.setItem('sizePerPage', val);
|
|
364
239
|
}
|
|
@@ -394,20 +269,10 @@ class itfView extends Vue {
|
|
|
394
269
|
this.loadData();
|
|
395
270
|
}
|
|
396
271
|
|
|
397
|
-
|
|
398
|
-
this.
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
getSorting() {
|
|
402
|
-
return this.sorting;
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
getFilter() {
|
|
406
|
-
return this.filter;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
getTableState() {
|
|
410
|
-
return this.$refs.table ? this.$refs.table.getTableState() : null;
|
|
272
|
+
loadFilters() {
|
|
273
|
+
if (this.filtersEndpoint) {
|
|
274
|
+
this.$refs.filters?.loadData();
|
|
275
|
+
}
|
|
411
276
|
}
|
|
412
277
|
}
|
|
413
278
|
</script>
|
|
@@ -8,12 +8,12 @@ const LINKED_IN_REGEXP = /(http(s)?:\/\/)?([\w]+\.)?linkedin\.com\/(pub|in|profi
|
|
|
8
8
|
const SPECIAL_CHARS_REGEXP = /^[\w_\-+~,/\\:'"().&*|[\]?# ]+$/i;
|
|
9
9
|
const GREETINGS_REGEXP = /\b(dr|mr|mister|mrs|ms|miss|sir|hello|hi)\b/i;
|
|
10
10
|
const PHONE_REGEXP = /(\+?\(?\+?[0-9]{1,3}\)?[-. ]+([0-9]{2,4})[-. ]?([0-9]{3,5}))|\+?[0-9]{7,}/gi;
|
|
11
|
+
const INTEGER_REGEXP = /^-?\d{0,11}$/;
|
|
11
12
|
const DOUBLE_REGEXP = /^-?\d{0,11}(\.\d{0,8}){0,1}$/;
|
|
12
|
-
const EMAIL_REGEXP =
|
|
13
|
+
const EMAIL_REGEXP = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/i;
|
|
13
14
|
const EMAIL_LIST_REGEXP = /^(\w+((-\w+)|(\.\w+))*@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]{2,4}\s*?,?\s*?)+$/g;
|
|
14
15
|
const HEX_REGEXP = /[0-9A-Fa-f]{6}/;
|
|
15
|
-
const
|
|
16
|
-
const PASSWORD_MAX_LENGTH = 50;
|
|
16
|
+
const PASSWORD_REGEX = /^(?=.*\p{Lu})(?=.*\p{Ll})(?=.*\d)(?=.*[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]).{8,}$/u;
|
|
17
17
|
|
|
18
18
|
const STANDART_DATE_FORMAT = 'yyyy-MM-dd';
|
|
19
19
|
|
|
@@ -67,6 +67,10 @@ export function emptyArrayValidation (message) {
|
|
|
67
67
|
return (v, $t = (s) => s) => (Array.isArray(v) && v.length > 0) || (message || $t('components.thisFieldIsRequired'));
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
+
export function integerValidation (message) {
|
|
71
|
+
return (v, $t = (s) => s) => !v || !!(v + '').match(INTEGER_REGEXP) || (message || $t('components.thisFieldMustBeANumberFormatZero'));
|
|
72
|
+
}
|
|
73
|
+
|
|
70
74
|
export function doubleValidation (message) {
|
|
71
75
|
return (v, $t = (s) => s) => !v || !!(v + '').match(DOUBLE_REGEXP) || (message || $t('components.thisFieldMustBeANumberFormatZero'));
|
|
72
76
|
}
|
|
@@ -184,38 +188,8 @@ export function dateSameOrBeforeValidation (dateCompare, message) {
|
|
|
184
188
|
};
|
|
185
189
|
}
|
|
186
190
|
|
|
187
|
-
export function
|
|
188
|
-
return (v, $t) => {
|
|
189
|
-
return !isEmpty(v) && /\p{Lu}/u.test(v + '') || (message || $t('components.atLeastOneUppercaseLetterRequired'));
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export function hasLowercaseValidation(message) {
|
|
194
|
-
return (v, $t) => {
|
|
195
|
-
return !isEmpty(v) && /\p{Ll}/u.test(v + '') || (message || $t('components.atLeastOneLowercaseLetterRequired'));
|
|
196
|
-
};
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
export function hasDigitValidation(message) {
|
|
200
|
-
return (v, $t) => {
|
|
201
|
-
return !isEmpty(v) && /\d/.test(v + '') || (message || $t('components.atLeastOneNumberRequired'));
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
export function hasSpecialCharValidation(message) {
|
|
191
|
+
export function passwordValidation(message) {
|
|
206
192
|
return (v, $t) => {
|
|
207
|
-
return !isEmpty(v) &&
|
|
193
|
+
return !isEmpty(v) && PASSWORD_REGEX.test(v.trim() + '') || (message || $t('components.passwordValidation'));
|
|
208
194
|
};
|
|
209
195
|
}
|
|
210
|
-
|
|
211
|
-
export function accountPasswordValidation(message) {
|
|
212
|
-
return [
|
|
213
|
-
emptyValidation(message),
|
|
214
|
-
minLengthValidation(PASSWORD_MIN_LENGTH, message),
|
|
215
|
-
lengthValidation(PASSWORD_MAX_LENGTH, message),
|
|
216
|
-
hasUppercaseValidation(message),
|
|
217
|
-
hasLowercaseValidation(message),
|
|
218
|
-
hasDigitValidation(message),
|
|
219
|
-
hasSpecialCharValidation(message),
|
|
220
|
-
];
|
|
221
|
-
}
|
|
@@ -7,10 +7,7 @@ import {
|
|
|
7
7
|
dateAfterValidation,
|
|
8
8
|
dateSameOrAfterValidation,
|
|
9
9
|
dateSameOrBeforeValidation,
|
|
10
|
-
|
|
11
|
-
hasLowercaseValidation,
|
|
12
|
-
hasDigitValidation,
|
|
13
|
-
hasSpecialCharValidation,
|
|
10
|
+
passwordValidation,
|
|
14
11
|
} from './validators';
|
|
15
12
|
|
|
16
13
|
describe('Validators', () => {
|
|
@@ -86,50 +83,16 @@ describe('Validators', () => {
|
|
|
86
83
|
expect(mediumTextValidation()('0'.repeat(16777216), $t)).toEqual('components.mediumTextLength');
|
|
87
84
|
});
|
|
88
85
|
|
|
89
|
-
test('hasUppercaseValidation', () => {
|
|
90
|
-
expect(hasUppercaseValidation()('', $t)).toEqual('components.atLeastOneUppercaseLetterRequired');
|
|
91
|
-
expect(hasUppercaseValidation()(' ', $t)).toEqual('components.atLeastOneUppercaseLetterRequired');
|
|
92
|
-
expect(hasUppercaseValidation()(null, $t)).toEqual('components.atLeastOneUppercaseLetterRequired');
|
|
93
|
-
expect(hasUppercaseValidation()(undefined, $t)).toEqual('components.atLeastOneUppercaseLetterRequired');
|
|
94
|
-
expect(hasUppercaseValidation()('A', $t)).toEqual(true);
|
|
95
|
-
expect(hasUppercaseValidation()(' Test ', $t)).toEqual(true);
|
|
96
|
-
expect(hasUppercaseValidation()(' test ', $t)).toEqual('components.atLeastOneUppercaseLetterRequired');
|
|
97
|
-
expect(hasUppercaseValidation()(' Тест ', $t)).toEqual(true);
|
|
98
|
-
expect(hasUppercaseValidation()(' тест ', $t)).toEqual('components.atLeastOneUppercaseLetterRequired');
|
|
99
|
-
expect(hasUppercaseValidation()(' ТЕСТ ', $t)).toEqual(true);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
test('hasLowercaseValidation', () => {
|
|
103
|
-
expect(hasLowercaseValidation()('', $t)).toEqual('components.atLeastOneLowercaseLetterRequired');
|
|
104
|
-
expect(hasLowercaseValidation()(' ', $t)).toEqual('components.atLeastOneLowercaseLetterRequired');
|
|
105
|
-
expect(hasLowercaseValidation()(null, $t)).toEqual('components.atLeastOneLowercaseLetterRequired');
|
|
106
|
-
expect(hasLowercaseValidation()(undefined, $t)).toEqual('components.atLeastOneLowercaseLetterRequired');
|
|
107
|
-
expect(hasLowercaseValidation()('a', $t)).toEqual(true);
|
|
108
|
-
expect(hasLowercaseValidation()(' test ', $t)).toEqual(true);
|
|
109
|
-
expect(hasLowercaseValidation()('A', $t)).toEqual('components.atLeastOneLowercaseLetterRequired');
|
|
110
|
-
expect(hasLowercaseValidation()(' Test ', $t)).toEqual(true);
|
|
111
|
-
expect(hasLowercaseValidation()(' Тест ', $t)).toEqual(true);
|
|
112
|
-
expect(hasLowercaseValidation()(' тест ', $t)).toEqual(true);
|
|
113
|
-
expect(hasLowercaseValidation()(' ТЕСТ ', $t)).toEqual('components.atLeastOneLowercaseLetterRequired');
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
test('hasDigitValidation', () => {
|
|
117
|
-
expect(hasDigitValidation()('', $t)).toEqual('components.atLeastOneNumberRequired');
|
|
118
|
-
expect(hasDigitValidation()(' ', $t)).toEqual('components.atLeastOneNumberRequired');
|
|
119
|
-
expect(hasDigitValidation()(null, $t)).toEqual('components.atLeastOneNumberRequired');
|
|
120
|
-
expect(hasDigitValidation()(undefined, $t)).toEqual('components.atLeastOneNumberRequired');
|
|
121
|
-
expect(hasDigitValidation()('1', $t)).toEqual(true);
|
|
122
|
-
expect(hasDigitValidation()(' 1 ', $t)).toEqual(true);
|
|
123
|
-
expect(hasDigitValidation()('a', $t)).toEqual('components.atLeastOneNumberRequired');
|
|
124
|
-
});
|
|
125
86
|
|
|
126
|
-
test('
|
|
127
|
-
expect(
|
|
128
|
-
expect(
|
|
129
|
-
expect(
|
|
130
|
-
expect(
|
|
131
|
-
expect(
|
|
132
|
-
expect(
|
|
133
|
-
expect(
|
|
87
|
+
test('passwordValidation', () => {
|
|
88
|
+
expect(passwordValidation()('', $t)).toEqual('components.passwordValidation');
|
|
89
|
+
expect(passwordValidation()(' ', $t)).toEqual('components.passwordValidation');
|
|
90
|
+
expect(passwordValidation()(null, $t)).toEqual('components.passwordValidation');
|
|
91
|
+
expect(passwordValidation()(undefined, $t)).toEqual('components.passwordValidation');
|
|
92
|
+
expect(passwordValidation()(' тесттест ', $t)).toEqual('components.passwordValidation');
|
|
93
|
+
expect(passwordValidation()(' ТЕСТТЕСТ ', $t)).toEqual('components.passwordValidation');
|
|
94
|
+
expect(passwordValidation()(' ТестТест ', $t)).toEqual('components.passwordValidation');
|
|
95
|
+
expect(passwordValidation()(' ТестТест1 ', $t)).toEqual('components.passwordValidation');
|
|
96
|
+
expect(passwordValidation()(' ТестТест1@ ', $t)).toEqual(true);
|
|
134
97
|
});
|
|
135
98
|
});
|