@itfin/components 1.2.92 → 1.2.94
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 +9 -10
- package/src/assets/scss/_bootstrap.scss +2 -1
- package/src/assets/scss/main.scss +2 -2
- package/src/components/customize/Inline/Select.vue +52 -0
- package/src/components/customize/PropertyInlineEdit.vue +22 -13
- package/src/components/customize/constants.js +2 -0
- package/src/components/modal/ItemEditor.vue +3 -0
- package/src/components/select/Select.vue +2 -1
- package/src/components/table/Table2.vue +48 -0
- package/src/components/table/TableBody.vue +34 -7
- package/src/components/table/TableGroup.vue +50 -28
- package/src/components/table/TableHeader.vue +48 -33
- package/src/components/table/TableRow.vue +1 -2
- package/src/components/table/index.stories.js +25 -61
- package/src/components/text-field/MoneyField.vue +8 -4
- package/src/assets/scss/boostrap.scss +0 -124
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itfin/components",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.94",
|
|
4
4
|
"author": "Vitalii Savchuk <esvit666@gmail.com>",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"serve": "vue-cli-service serve",
|
|
@@ -24,24 +24,23 @@
|
|
|
24
24
|
"@popperjs/core": "^2.11.8",
|
|
25
25
|
"@shopify/draggable": "^1.0.0-beta.8",
|
|
26
26
|
"@vue/cli-service": "^5.0.1",
|
|
27
|
-
"@vue/composition-api": "^1.7.1",
|
|
28
27
|
"air-datepicker": "^3.3.5",
|
|
29
|
-
"bootstrap": "^5.
|
|
30
|
-
"core-js": "^3.
|
|
28
|
+
"bootstrap": "^5.3.0",
|
|
29
|
+
"core-js": "^3.31.1",
|
|
31
30
|
"debug": "^4.2.0",
|
|
32
31
|
"intersection-observer": "^0.12.2",
|
|
33
32
|
"lodash": "^4.17.20",
|
|
34
33
|
"luxon": "^3.3.0",
|
|
35
|
-
"pdfjs-dist": "^
|
|
34
|
+
"pdfjs-dist": "^3.8.162",
|
|
36
35
|
"tippy.js": "^6.3.2",
|
|
37
|
-
"vue": "^2.6.12",
|
|
38
36
|
"vue-imask": "^6.6.3",
|
|
39
37
|
"vue-property-decorator": "^9.1.2",
|
|
40
38
|
"vue-swatches": "^2.1.1",
|
|
41
39
|
"vue-virtual-scroller": "^1.1.2"
|
|
42
40
|
},
|
|
43
41
|
"devDependencies": {
|
|
44
|
-
"
|
|
42
|
+
"vue": "^2.6.12",
|
|
43
|
+
"@babel/eslint-parser": "^7.22.9",
|
|
45
44
|
"@babel/plugin-proposal-numeric-separator": "^7.18.6",
|
|
46
45
|
"@babel/plugin-syntax-numeric-separator": "^7.10.4",
|
|
47
46
|
"@storybook/addon-docs": "=6.3.8",
|
|
@@ -53,10 +52,10 @@
|
|
|
53
52
|
"@vue/eslint-config-airbnb": "^7.0.0",
|
|
54
53
|
"@vue/test-utils": "^1.1.1",
|
|
55
54
|
"babel-eslint": "^10.1.0",
|
|
56
|
-
"eslint": "^8.
|
|
57
|
-
"eslint-plugin-import": "^2.
|
|
55
|
+
"eslint": "^8.45.0",
|
|
56
|
+
"eslint-plugin-import": "^2.27.5",
|
|
58
57
|
"eslint-plugin-prettier": "^4.2.1",
|
|
59
|
-
"eslint-plugin-vue": "^9.
|
|
58
|
+
"eslint-plugin-vue": "^9.15.1",
|
|
60
59
|
"fibers": "^5.0.0",
|
|
61
60
|
"marked": "^4.2.5",
|
|
62
61
|
"sass": "^1.29.0",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
// Include remainder of required Bootstrap stylesheets
|
|
5
5
|
@import "~bootstrap/scss/variables.scss";
|
|
6
|
+
$enable-dark-mode: false;
|
|
6
7
|
@import "~bootstrap/scss/mixins.scss";
|
|
7
8
|
@import "~bootstrap/scss/maps.scss";
|
|
8
9
|
@import "~bootstrap/scss/utilities.scss";
|
|
@@ -31,4 +32,4 @@ $utilities: map-merge(
|
|
|
31
32
|
),
|
|
32
33
|
)
|
|
33
34
|
);
|
|
34
|
-
//@import "~bootstrap/scss/utilities/api"; // створює дублікати класів, які вже є в bootstrap
|
|
35
|
+
//@import "~bootstrap/scss/utilities/api"; // створює дублікати класів, які вже є в bootstrap
|
|
@@ -50,11 +50,11 @@
|
|
|
50
50
|
|
|
51
51
|
kbd {
|
|
52
52
|
background-color: rgba(0, 0, 0, .15) !important;
|
|
53
|
-
color:
|
|
53
|
+
color: var(--bs-body-color) !important;
|
|
54
54
|
font-size: .75rem !important;
|
|
55
55
|
|
|
56
56
|
[data-theme="dark"] &, .btn-primary & {
|
|
57
57
|
background-color: rgba(255, 255, 255, .25) !important;
|
|
58
|
-
color:
|
|
58
|
+
color: var(--bs-primary-color) !important
|
|
59
59
|
}
|
|
60
60
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<itf-select
|
|
3
|
+
ref="input"
|
|
4
|
+
class="itf-inline-edit flex-grow-1"
|
|
5
|
+
role="button"
|
|
6
|
+
:placeholder="focused ? 'Search for an option...' : 'Empty'"
|
|
7
|
+
:tabindex="1"
|
|
8
|
+
:disabled="!editable"
|
|
9
|
+
:options="field && field.Options"
|
|
10
|
+
:reduce="option => option.Name"
|
|
11
|
+
:get-option-label="option => option.Name"
|
|
12
|
+
@search:focus="$emit('focus')"
|
|
13
|
+
@search:blur="$emit('blur')">
|
|
14
|
+
<template #option="{ option }">
|
|
15
|
+
<div>{{ option.Name }}</div>
|
|
16
|
+
</template>
|
|
17
|
+
</itf-select>
|
|
18
|
+
</template>
|
|
19
|
+
<style lang="scss">
|
|
20
|
+
.itf-inline-edit.itf-select .form-control {
|
|
21
|
+
border: 0 none;
|
|
22
|
+
margin: 0;
|
|
23
|
+
outline: 0;
|
|
24
|
+
resize: none;
|
|
25
|
+
min-height: auto;
|
|
26
|
+
padding: 0.1rem 0;
|
|
27
|
+
font-family: var(--bs-body-font-family);
|
|
28
|
+
font-size: var(--bs-body-font-size);
|
|
29
|
+
box-shadow: none !important;
|
|
30
|
+
background: transparent !important;
|
|
31
|
+
}
|
|
32
|
+
</style>
|
|
33
|
+
<script>
|
|
34
|
+
import {Vue, Component, Model, Watch, Prop} from 'vue-property-decorator';
|
|
35
|
+
import itfTextField from '../../text-field/TextField.vue';
|
|
36
|
+
import itfSelect from '../../select/Select.vue';
|
|
37
|
+
|
|
38
|
+
export default @Component({
|
|
39
|
+
name: 'itfCustomizeInlineSelect',
|
|
40
|
+
components: {
|
|
41
|
+
itfTextField,
|
|
42
|
+
itfSelect
|
|
43
|
+
}
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
class itfCustomizeInlineSelect extends Vue {
|
|
47
|
+
@Model('input') value;
|
|
48
|
+
@Prop(Boolean) focused;
|
|
49
|
+
@Prop(Boolean) editable;
|
|
50
|
+
@Prop() field;
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
</div>
|
|
2
|
+
<component
|
|
3
|
+
v-if="component"
|
|
4
|
+
class="h-100 w-100 d-flex align-items-center"
|
|
5
|
+
:is="component"
|
|
6
|
+
:value="value"
|
|
7
|
+
:field="field"
|
|
8
|
+
:focused="focused"
|
|
9
|
+
:editable="editable"
|
|
10
|
+
@input="$emit('input', $event)"
|
|
11
|
+
@focus="onFocus(); $emit('focus')"
|
|
12
|
+
@blur="onBlur(); $emit('blur')"
|
|
13
|
+
/>
|
|
15
14
|
</template>
|
|
16
15
|
<script>
|
|
17
16
|
import { Vue, Component, Model, Prop } from 'vue-property-decorator';
|
|
@@ -33,6 +32,16 @@ class itfPropertyInlineEdit extends Vue {
|
|
|
33
32
|
@Prop(Boolean) focused;
|
|
34
33
|
@Prop(Boolean) editable;
|
|
35
34
|
|
|
35
|
+
isFocused = false;
|
|
36
|
+
|
|
37
|
+
onFocus() {
|
|
38
|
+
this.isFocused = true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
onBlur() {
|
|
42
|
+
this.isFocused = false;
|
|
43
|
+
}
|
|
44
|
+
|
|
36
45
|
get component() {
|
|
37
46
|
if (!this.field) {
|
|
38
47
|
return null;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import InlineText from './Inline/Text';
|
|
2
2
|
import InlineDate from './Inline/Date';
|
|
3
3
|
import InlineMultiselect from './Inline/Multiselect.vue';
|
|
4
|
+
import InlineSelect from './Inline/Select.vue';
|
|
4
5
|
|
|
5
6
|
export const INLINE_TYPES = [
|
|
6
7
|
{ Type: 'text', Name: 'Text', Icon: 'type_text', Component: InlineText },
|
|
7
8
|
{ Type: 'date', Name: 'Date', Icon: 'type_date', Component: InlineDate },
|
|
8
9
|
{ Type: 'multiselect', Name: 'Multiselect', Icon: 'type_multiselect', Component: InlineMultiselect },
|
|
10
|
+
{ Type: 'select', Name: 'Select', Icon: 'type_select', Component: InlineSelect },
|
|
9
11
|
];
|
|
@@ -626,7 +626,8 @@ export default {
|
|
|
626
626
|
default(dropdownList, component, { width, top, left }) {
|
|
627
627
|
dropdownList.style.top = top
|
|
628
628
|
dropdownList.style.left = left
|
|
629
|
-
dropdownList.style.
|
|
629
|
+
dropdownList.style.minWidth = width
|
|
630
|
+
dropdownList.style.width = 'max-content';
|
|
630
631
|
},
|
|
631
632
|
},
|
|
632
633
|
/**
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
|
|
3
|
+
<div class="scrollable scrollable-x big-scrollbar">
|
|
4
|
+
<itf-table-group
|
|
5
|
+
:columns="columns"
|
|
6
|
+
:rows="rows"
|
|
7
|
+
:add-new-rows="addNewRows"
|
|
8
|
+
>
|
|
9
|
+
<template v-for="(_, name) in $slots" #[name]="slotData">
|
|
10
|
+
<slot :name="name" v-bind="slotData || {}" />
|
|
11
|
+
</template>
|
|
12
|
+
<template v-for="(_, name) in $scopedSlots" #[name]="slotData">
|
|
13
|
+
<slot :name="name" v-bind="slotData || {}" />
|
|
14
|
+
</template>
|
|
15
|
+
</itf-table-group>
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
</template>
|
|
19
|
+
<style lang="scss">
|
|
20
|
+
//.scrollable {
|
|
21
|
+
// -webkit-overflow-scrolling: touch;
|
|
22
|
+
// overflow: hidden auto;
|
|
23
|
+
//
|
|
24
|
+
// &.scrollable-x {
|
|
25
|
+
// overflow-x: auto;
|
|
26
|
+
// }
|
|
27
|
+
//}
|
|
28
|
+
</style>
|
|
29
|
+
<script>
|
|
30
|
+
import { Vue, Component, Prop, PropSync } from 'vue-property-decorator';
|
|
31
|
+
import itfButton from '../button/Button.vue';
|
|
32
|
+
import itfIcon from '../icon/Icon.vue';
|
|
33
|
+
import itfTableGroup from './TableGroup.vue';
|
|
34
|
+
|
|
35
|
+
export default @Component({
|
|
36
|
+
name: 'itfTable2',
|
|
37
|
+
components: {
|
|
38
|
+
itfButton,
|
|
39
|
+
itfIcon,
|
|
40
|
+
itfTableGroup
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
class itfTable2 extends Vue {
|
|
44
|
+
@Prop({ required: true, type: Array }) columns;
|
|
45
|
+
@Prop({ required: true, type: Array }) rows;
|
|
46
|
+
@Prop(Boolean) addNewRows;
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
@@ -38,11 +38,13 @@
|
|
|
38
38
|
</div>
|
|
39
39
|
</div>
|
|
40
40
|
<div accept-group="items" class="hbox table-item-inner">
|
|
41
|
-
<div v-for="(column, n) in columns" :data-column="n" :style="`width: ${column.width}px`">
|
|
42
|
-
<
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
<div v-for="(column, n) in columns" :data-column="n" :style="`width: ${column.width}px`" class="table-view-item-value d-flex position-relative h-100 align-items-stretch px-2">
|
|
42
|
+
<slot :name="`column.${column.name}`" :item="item" :column="column">
|
|
43
|
+
<template v-if="editTypes[column.Type]">
|
|
44
|
+
<property-inline-edit :value="item[column.field]" :field="column" editable focused />
|
|
45
|
+
</template>
|
|
46
|
+
<div v-else v-text="item.Name" />
|
|
47
|
+
</slot>
|
|
46
48
|
</div>
|
|
47
49
|
|
|
48
50
|
<div class="table-view-item-value extra"></div>
|
|
@@ -79,6 +81,7 @@
|
|
|
79
81
|
height: 100%;
|
|
80
82
|
display: flex;
|
|
81
83
|
position: relative;
|
|
84
|
+
line-height: 35px;
|
|
82
85
|
|
|
83
86
|
&:hover {
|
|
84
87
|
background-color: rgb(250 251 252 / 1);
|
|
@@ -101,6 +104,9 @@
|
|
|
101
104
|
background-color: rgb(255 255 255 / 1);
|
|
102
105
|
border-right: 1px solid rgb(238 238 238 / 1);
|
|
103
106
|
border-bottom: 1px solid rgb(238 238 238 / 1);
|
|
107
|
+
display: flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
justify-content: center;
|
|
104
110
|
}
|
|
105
111
|
|
|
106
112
|
.table-item-inner .boundary {
|
|
@@ -140,23 +146,44 @@
|
|
|
140
146
|
.vue-recycle-scroller {
|
|
141
147
|
position: relative;
|
|
142
148
|
}
|
|
149
|
+
.resize-observer {
|
|
150
|
+
position: absolute;
|
|
151
|
+
top: 0;
|
|
152
|
+
left: 0;
|
|
153
|
+
z-index: -1;
|
|
154
|
+
width: 100%;
|
|
155
|
+
height: 100%;
|
|
156
|
+
border: none;
|
|
157
|
+
background-color: transparent;
|
|
158
|
+
pointer-events: none;
|
|
159
|
+
display: block;
|
|
160
|
+
overflow: hidden;
|
|
161
|
+
opacity: 0;
|
|
162
|
+
}
|
|
143
163
|
</style>
|
|
144
|
-
|
|
145
164
|
<script>
|
|
146
165
|
import { Vue, Component, Prop } from 'vue-property-decorator';
|
|
147
166
|
import { RecycleScroller } from 'vue-virtual-scroller'
|
|
167
|
+
import PropertyInlineEdit from '../customize/PropertyInlineEdit.vue';
|
|
168
|
+
import { INLINE_TYPES } from '@/components/customize/constants';
|
|
148
169
|
|
|
149
170
|
export default @Component({
|
|
150
171
|
name: 'itfTableBody',
|
|
151
172
|
components: {
|
|
152
|
-
RecycleScroller
|
|
173
|
+
RecycleScroller,
|
|
174
|
+
PropertyInlineEdit
|
|
153
175
|
}
|
|
154
176
|
})
|
|
155
177
|
class itfTableBody extends Vue {
|
|
156
178
|
@Prop() columns;
|
|
157
179
|
@Prop() rows;
|
|
158
180
|
|
|
181
|
+
editTypes = {};
|
|
182
|
+
|
|
159
183
|
mounted() {
|
|
184
|
+
for (const { Type } of INLINE_TYPES) {
|
|
185
|
+
this.editTypes[Type] = true;
|
|
186
|
+
}
|
|
160
187
|
}
|
|
161
188
|
}
|
|
162
189
|
</script>
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
<div class="itf-table-group table-small-row">
|
|
4
4
|
<!-- Тут показується лінія при драг н дропі -->
|
|
5
|
-
<div accept-group="tablegroups" class="preline
|
|
5
|
+
<div accept-group="tablegroups" class="preline">
|
|
6
6
|
<div class="line"></div>
|
|
7
7
|
</div>
|
|
8
8
|
|
|
9
|
-
|
|
10
9
|
<div data-test="table-group-wrapper" class="table-group-wrapper" :style="`--row-count: ${isShowTable ? rows.length : 0}`">
|
|
11
10
|
<div class="">
|
|
12
11
|
<div data-test="table-group" class="position-relative me-4">
|
|
@@ -18,11 +17,11 @@
|
|
|
18
17
|
<a href="" class="collapse-arrow" @click.prevent="toggleGroup">
|
|
19
18
|
<itf-icon :name="isShowTable ? 'chevron_down' : 'chevron_right'" />
|
|
20
19
|
</a>
|
|
21
|
-
<
|
|
20
|
+
<span class="d-flex align-items-center line-overflow group-header-value" data-test="group-value-group-label-value">
|
|
22
21
|
<span title="To Do" class="badge text-decoration-none" style="background-color: #FFA2A2; color: #4C4E69;">To Do</span>
|
|
23
|
-
</
|
|
22
|
+
</span>
|
|
24
23
|
<div data-test="table-group-item-count" class="table-group-item-count">
|
|
25
|
-
|
|
24
|
+
{{rows.length}}
|
|
26
25
|
</div>
|
|
27
26
|
</div>
|
|
28
27
|
</div>
|
|
@@ -32,25 +31,32 @@
|
|
|
32
31
|
<!-- Сама таблиця -->
|
|
33
32
|
<div v-if="isShowTable" class="table-view-body">
|
|
34
33
|
<itf-table-header :columns="columns" />
|
|
35
|
-
<itf-table-body :rows="rows" :columns="columns"
|
|
34
|
+
<itf-table-body :rows="rows" :columns="columns">
|
|
35
|
+
<template v-for="(_, name) in $slots" #[name]="slotData">
|
|
36
|
+
<slot :name="name" v-bind="slotData || {}" />
|
|
37
|
+
</template>
|
|
38
|
+
<template v-for="(_, name) in $scopedSlots" #[name]="slotData">
|
|
39
|
+
<slot :name="name" v-bind="slotData || {}" />
|
|
40
|
+
</template>
|
|
41
|
+
</itf-table-body>
|
|
36
42
|
</div>
|
|
37
43
|
|
|
38
44
|
<!-- Лінія додати нову -->
|
|
39
|
-
<div v-if="isShowTable"
|
|
40
|
-
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
<div v-if="isShowTable && addNewRows" class="table-row-template d-flex align-items-stretch">
|
|
46
|
+
<div class="shadow-area"></div>
|
|
47
|
+
<a href="" data-test="table-add-new-item" class="d-flex align-items-center flex-grow-1 table-add-new-item">
|
|
48
|
+
<span class="d-sticky d-flex align-items-center px-2">
|
|
49
|
+
<itf-icon name="plus" />
|
|
50
|
+
<span>Add new row</span>
|
|
51
|
+
</span>
|
|
52
|
+
</a>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
48
55
|
<!-- Групування -->
|
|
49
|
-
<div v-if="
|
|
50
|
-
class="table-row-template
|
|
51
|
-
<div
|
|
52
|
-
<div
|
|
53
|
-
class="tw-flex tw-flex-row tw-items-center tw-ml-[var(--indicator-area-width)]"><span
|
|
56
|
+
<div v-if="showGrouping"
|
|
57
|
+
class="table-row-template d-flex align-items-stretch tw-h-[var(--table-small-row-size)] table-summary">
|
|
58
|
+
<div class="tw-bg-light dark:tw-bg-light-invert shadow-area"></div>
|
|
59
|
+
<div class="d-flex tw-flex-row align-items-center tw-ml-[var(--indicator-area-width)]"><span
|
|
54
60
|
data-v-54c5481c="" data-column="0" class="tw-relative line-overflow"
|
|
55
61
|
style="width: 400px;"><a href=""
|
|
56
62
|
class="context-menu-toggle tw-w-full tw-text-gray dark:tw-text-gray-invert tw-text-sm tw-flex tw-pr-3 tw-flex tw-items-stretch tw-justify-end"
|
|
@@ -112,6 +118,13 @@
|
|
|
112
118
|
--shadow-area-width: 45px;
|
|
113
119
|
--indicator-area-width: 38px;
|
|
114
120
|
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
min-width: 100%;
|
|
123
|
+
display: flex;
|
|
124
|
+
width: fit-content;
|
|
125
|
+
margin-top: 20px;
|
|
126
|
+
margin-bottom: 20px;
|
|
127
|
+
|
|
115
128
|
.preline {
|
|
116
129
|
display: flex;
|
|
117
130
|
align-items: center;
|
|
@@ -140,6 +153,7 @@
|
|
|
140
153
|
position: sticky;
|
|
141
154
|
left: 0;
|
|
142
155
|
background: #fff;
|
|
156
|
+
border-right: 1px solid rgb(238, 238, 238);
|
|
143
157
|
}
|
|
144
158
|
.header-wrapper:not(.collapsed *) {
|
|
145
159
|
flex-grow: 1;
|
|
@@ -174,14 +188,8 @@
|
|
|
174
188
|
background-color: rgb(250 251 252 / 1);
|
|
175
189
|
border-radius: 0.1875rem;
|
|
176
190
|
}
|
|
177
|
-
.vue-recycle-scroller__item-wrapper {
|
|
178
|
-
|
|
179
|
-
-ms-flex: 1;
|
|
180
|
-
flex: 1;
|
|
181
|
-
-webkit-box-sizing: border-box;
|
|
182
|
-
box-sizing: border-box;
|
|
183
|
-
overflow: hidden;
|
|
184
|
-
position: relative;
|
|
191
|
+
.table-view-wrapper .vue-recycle-scroller__item-wrapper {
|
|
192
|
+
overflow: visible;
|
|
185
193
|
}
|
|
186
194
|
.vue-recycle-scroller.direction-vertical .vue-recycle-scroller__item-wrapper {
|
|
187
195
|
width: 100%;
|
|
@@ -195,6 +203,18 @@
|
|
|
195
203
|
left: 0;
|
|
196
204
|
will-change: transform;
|
|
197
205
|
}
|
|
206
|
+
.table-row-template {
|
|
207
|
+
height: var(--table-small-row-size);
|
|
208
|
+
}
|
|
209
|
+
.table-add-new-item {
|
|
210
|
+
border-right: 1px solid rgb(238 238 238 / 1);
|
|
211
|
+
border-bottom: 1px solid rgb(238 238 238 / 1);
|
|
212
|
+
|
|
213
|
+
& > span {
|
|
214
|
+
left: var(--shadow-area-width);
|
|
215
|
+
position: sticky;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
198
218
|
}
|
|
199
219
|
</style>
|
|
200
220
|
<script>
|
|
@@ -216,6 +236,8 @@ export default @Component({
|
|
|
216
236
|
class itfTableGroup extends Vue {
|
|
217
237
|
@Prop() columns;
|
|
218
238
|
@Prop() rows;
|
|
239
|
+
@Prop(Boolean) showGrouping;
|
|
240
|
+
@Prop(Boolean) addNewRows;
|
|
219
241
|
|
|
220
242
|
isShowTable = true;
|
|
221
243
|
|
|
@@ -7,38 +7,40 @@
|
|
|
7
7
|
<div class="table-view-header-value reserved sticky"></div>
|
|
8
8
|
|
|
9
9
|
<div v-for="(column, n) in sortedColumns" :key="n" data-test="table-header-column" :data-column="n" :data-id="column.Id"
|
|
10
|
-
class="table-view-header-value" style="width:
|
|
10
|
+
class="table-view-header-value" :style="`width: ${column.width}px; left: 0px;`">
|
|
11
11
|
<div accept-group="tablecolumns" class="table-view-header-space">
|
|
12
12
|
<div class="table-view-header-dropzone"></div>
|
|
13
13
|
</div>
|
|
14
|
-
<div group="tablecolumns" class="table-header draggable-item drag-handle"
|
|
15
|
-
<
|
|
16
|
-
<span title="
|
|
17
|
-
<itf-icon name="type_select" :size="16"
|
|
14
|
+
<div group="tablecolumns" class="table-header draggable-item drag-handle">
|
|
15
|
+
<span href="" class="context-menu-toggle flex-auto line-overflow">
|
|
16
|
+
<span :title="column.text">
|
|
17
|
+
<!-- <itf-icon name="type_select" :size="16" />-->
|
|
18
|
+
{{column.text}}
|
|
18
19
|
</span>
|
|
19
|
-
</
|
|
20
|
+
</span>
|
|
20
21
|
</div>
|
|
21
|
-
<div ref="resizeHandle" class="resize-handle"></div>
|
|
22
|
+
<div v-if="columnResizing" ref="resizeHandle" class="resize-handle"></div>
|
|
22
23
|
</div>
|
|
23
24
|
|
|
24
|
-
|
|
25
|
-
<div
|
|
26
|
-
<div data-
|
|
27
|
-
class="dropdown-body tw-relative tw-cursor-pointer tw-w-full"
|
|
28
|
-
<div
|
|
29
|
-
<div
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
</a></div>
|
|
25
|
+
<!--div class="table-view-header-value">
|
|
26
|
+
<div class="attribute-creator">
|
|
27
|
+
<div data-test="dropdown"
|
|
28
|
+
class="dropdown-body tw-relative tw-cursor-pointer tw-w-full">
|
|
29
|
+
<div tabindex="0" data-test="dropdown-toggle">
|
|
30
|
+
<div class="hbox tw-flex-auto tw-items-center tw-justify-center">
|
|
31
|
+
<a href="" data-test="table-header-add-column" class="tw-text-blue tw-mx-4">
|
|
32
|
+
<span class="ic-plus"></span>
|
|
33
|
+
Add column
|
|
34
|
+
</a>
|
|
35
|
+
</div>
|
|
36
36
|
</div>
|
|
37
|
-
<span
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
<span style="display: none;">
|
|
38
|
+
<div class="context-modal-backdrop"></div>
|
|
39
|
+
<div class="context-modal tw-min-w-[280px]"></div>
|
|
40
|
+
</span>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div-->
|
|
42
44
|
</div>
|
|
43
45
|
</div>
|
|
44
46
|
|
|
@@ -161,7 +163,7 @@
|
|
|
161
163
|
import { Vue, Component, Prop, PropSync } from 'vue-property-decorator';
|
|
162
164
|
import itfButton from '../button/Button.vue';
|
|
163
165
|
import itfIcon from '../icon/Icon.vue';
|
|
164
|
-
import { Draggable, Droppable } from '@shopify/draggable';
|
|
166
|
+
import { Draggable, Droppable, Sortable } from '@shopify/draggable';
|
|
165
167
|
|
|
166
168
|
export default @Component({
|
|
167
169
|
name: 'itfTableHeader',
|
|
@@ -172,24 +174,28 @@ export default @Component({
|
|
|
172
174
|
})
|
|
173
175
|
class itfTable extends Vue {
|
|
174
176
|
@PropSync('columns', { type: Array, default: () => ([]) }) sortedColumns;
|
|
177
|
+
@Prop(Boolean) columnSorting;
|
|
178
|
+
@Prop(Boolean) columnResizing;
|
|
175
179
|
|
|
176
|
-
|
|
177
|
-
const draggable = new
|
|
178
|
-
draggable: '[group="tablecolumns"]',
|
|
180
|
+
initDraggable() {
|
|
181
|
+
const draggable = new Sortable(this.$refs.container, {
|
|
182
|
+
// draggable: '[group="tablecolumns"]',
|
|
183
|
+
draggable: '[data-test="table-header-column"]',
|
|
179
184
|
mirror: {
|
|
180
185
|
yAxis: false,
|
|
181
186
|
appendTo: this.$refs.container
|
|
182
187
|
}
|
|
183
188
|
});
|
|
184
|
-
const droppable = new Droppable(this.$refs.container, {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
});
|
|
189
|
+
// const droppable = new Droppable(this.$refs.container, {
|
|
190
|
+
// draggable: '[group="tablecolumns"]',
|
|
191
|
+
// dropzone: '[accept-group="tablecolumns"]'
|
|
192
|
+
// });
|
|
188
193
|
draggable.on('drag:stop', (event) => {
|
|
189
194
|
console.info('dropped', event);
|
|
190
195
|
});
|
|
196
|
+
}
|
|
191
197
|
|
|
192
|
-
|
|
198
|
+
initResizing() {
|
|
193
199
|
const resizeHandle = this.$refs.resizeHandle;
|
|
194
200
|
resizeHandle.forEach((handle) => {
|
|
195
201
|
handle.addEventListener('mousedown', (event) => {
|
|
@@ -216,6 +222,15 @@ class itfTable extends Vue {
|
|
|
216
222
|
});
|
|
217
223
|
}
|
|
218
224
|
|
|
225
|
+
mounted() {
|
|
226
|
+
if (this.columnSorting) {
|
|
227
|
+
this.initDraggable();
|
|
228
|
+
}
|
|
229
|
+
if (this.columnResizing) {
|
|
230
|
+
this.initResizing();
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
219
234
|
changeColumn(index, params) {
|
|
220
235
|
console.info(index, params);
|
|
221
236
|
}
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
class="ic-drag"></i>
|
|
15
15
|
</div> <!----></a></div>
|
|
16
16
|
</div>
|
|
17
|
-
<div
|
|
18
|
-
class="indicator sticky border-gray dark:border-gray-invert border-r bg-white dark:bg-white-invert border-b ">
|
|
17
|
+
<div class="indicator">
|
|
19
18
|
<div class="fill on-rest table-view-row-count"><span
|
|
20
19
|
>1</span></div>
|
|
21
20
|
<div class="fill on-hover"><a
|
|
@@ -2,7 +2,7 @@ import { storiesOf } from '@storybook/vue';
|
|
|
2
2
|
import itfApp from '../app/App.vue';
|
|
3
3
|
import itfButton from '../button/Button.vue';
|
|
4
4
|
import itfTable from './Table.vue';
|
|
5
|
-
import
|
|
5
|
+
import itfTable2 from './Table2.vue';
|
|
6
6
|
|
|
7
7
|
const exampleData = [{
|
|
8
8
|
Employee: 'Cool',
|
|
@@ -77,82 +77,41 @@ storiesOf('Common', module)
|
|
|
77
77
|
components: {
|
|
78
78
|
itfTable,
|
|
79
79
|
itfButton,
|
|
80
|
-
|
|
80
|
+
itfTable2
|
|
81
81
|
},
|
|
82
82
|
data() {
|
|
83
83
|
return {
|
|
84
|
-
list: Array.from({length:
|
|
84
|
+
list: Array.from({length: 10}).map((_, i) => ({
|
|
85
85
|
Id: i,
|
|
86
|
+
text: `Рахунок`,
|
|
86
87
|
Name: `Item #${i}`
|
|
87
88
|
})),
|
|
88
89
|
columns: [{
|
|
89
|
-
text: '
|
|
90
|
-
name: '
|
|
90
|
+
text: 'Рахунок',
|
|
91
|
+
name: 'Account',
|
|
91
92
|
width: 200,
|
|
92
93
|
min: 250,
|
|
93
94
|
max: 250
|
|
94
95
|
}, {
|
|
95
|
-
text: '
|
|
96
|
+
text: 'Dr',
|
|
96
97
|
name: 'Total',
|
|
98
|
+
Type: 'select',
|
|
99
|
+
Options: [
|
|
100
|
+
{ Id: 1, Name: '10.10.12.31 - test фів фівіф в вфів фвф' }
|
|
101
|
+
],
|
|
97
102
|
width: 200,
|
|
98
103
|
min: 150,
|
|
99
104
|
max: 150
|
|
100
105
|
}, {
|
|
101
|
-
text: '
|
|
102
|
-
name: '
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
text: 'Position',
|
|
108
|
-
name: 'Position',
|
|
109
|
-
width: 200,
|
|
110
|
-
min: 200,
|
|
111
|
-
max: 200
|
|
112
|
-
}, {
|
|
113
|
-
text: 'Office',
|
|
114
|
-
name: 'Office',
|
|
115
|
-
width: 200,
|
|
116
|
-
min: 150,
|
|
117
|
-
max: 150
|
|
118
|
-
}, {
|
|
119
|
-
text: 'Internal',
|
|
120
|
-
name: 'MinutesInternal',
|
|
121
|
-
width: 200,
|
|
122
|
-
min: 150,
|
|
123
|
-
max: 150,
|
|
124
|
-
sortable: true
|
|
125
|
-
}, {
|
|
126
|
-
text: 'External',
|
|
127
|
-
name: 'MinutesExternal',
|
|
128
|
-
width: 200,
|
|
129
|
-
min: 150,
|
|
130
|
-
max: 150,
|
|
131
|
-
sortable: true
|
|
132
|
-
}, {
|
|
133
|
-
text: 'Compensation (Internal)',
|
|
134
|
-
name: 'AmountInternal',
|
|
135
|
-
width: 200,
|
|
136
|
-
min: 200,
|
|
137
|
-
max: 200
|
|
138
|
-
}, {
|
|
139
|
-
text: 'Compensation (External)',
|
|
140
|
-
name: 'AmountExternal',
|
|
141
|
-
width: 200,
|
|
142
|
-
min: 150,
|
|
143
|
-
max: 150
|
|
144
|
-
}, {
|
|
145
|
-
text: 'Bonus/Commission',
|
|
146
|
-
name: 'AmountShare',
|
|
106
|
+
text: 'Cr',
|
|
107
|
+
name: 'Total',
|
|
108
|
+
Type: 'select',
|
|
109
|
+
Options: [
|
|
110
|
+
{ Id: 1, Name: 'test' }
|
|
111
|
+
],
|
|
147
112
|
width: 200,
|
|
148
113
|
min: 150,
|
|
149
114
|
max: 150
|
|
150
|
-
}, {
|
|
151
|
-
text: 'Actions',
|
|
152
|
-
name: 'Notes',
|
|
153
|
-
width: 200,
|
|
154
|
-
min: 80,
|
|
155
|
-
max: 80
|
|
156
115
|
}]
|
|
157
116
|
}
|
|
158
117
|
},
|
|
@@ -172,9 +131,14 @@ storiesOf('Common', module)
|
|
|
172
131
|
|
|
173
132
|
<h3>Example</h3>
|
|
174
133
|
|
|
175
|
-
<itf-
|
|
176
|
-
|
|
177
|
-
|
|
134
|
+
<itf-table2 :columns="columns" :rows="list">
|
|
135
|
+
<template #column.Account="{ item }">
|
|
136
|
+
{{item.text}}
|
|
137
|
+
</template>
|
|
138
|
+
<template #column.FTE="{ item }">
|
|
139
|
+
{{item}}
|
|
140
|
+
</template>
|
|
141
|
+
</itf-table2>
|
|
178
142
|
|
|
179
143
|
<!--itf-table
|
|
180
144
|
:columns="columns"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="itf-money-field" :class="{'currency-arrow': !currencyDisabled}">
|
|
2
|
+
<div class="itf-money-field" :class="{'currency-arrow': !currencyDisabled, 'currency-select': currencySelect}">
|
|
3
3
|
<div :style="`--itf-money-field-padding-left: ${selectedCurrencySymbol.length * 0.6 + 1}rem`">
|
|
4
4
|
<span class="itf-money-field__prepend">{{ selectedCurrencySymbol }}</span>
|
|
5
5
|
<itf-text-field
|
|
@@ -27,15 +27,19 @@
|
|
|
27
27
|
|
|
28
28
|
.itf-text-field input {
|
|
29
29
|
padding-left: var(--itf-money-field-padding-left, 1.5rem);
|
|
30
|
-
padding-right: 3rem;
|
|
31
30
|
|
|
32
31
|
&.is-invalid, &.is-valid {
|
|
33
32
|
padding-right: 4rem;
|
|
34
33
|
}
|
|
35
34
|
}
|
|
36
|
-
&.currency-
|
|
35
|
+
&.currency-select {
|
|
37
36
|
.itf-text-field input {
|
|
38
|
-
padding-right:
|
|
37
|
+
padding-right: 3rem;
|
|
38
|
+
}
|
|
39
|
+
&.currency-arrow {
|
|
40
|
+
.itf-text-field input {
|
|
41
|
+
padding-right: 4.5rem;
|
|
42
|
+
}
|
|
39
43
|
}
|
|
40
44
|
}
|
|
41
45
|
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
// 1. Include functions first (so you can manipulate colors, SVGs, calc, etc)
|
|
2
|
-
@import "~bootstrap/scss/functions.scss";
|
|
3
|
-
|
|
4
|
-
// 2. Include any default variable overrides here
|
|
5
|
-
$font-family-base: 'Fira Sans', sans-serif;
|
|
6
|
-
$headings-font-family: 'Fira Sans', sans-serif;
|
|
7
|
-
$font-family-monospace: "Fira Mono", "Courier New", monospace;
|
|
8
|
-
|
|
9
|
-
$headings-font-size-base: 1rem;
|
|
10
|
-
$h1-font-size: $headings-font-size-base * 2;
|
|
11
|
-
$h2-font-size: $headings-font-size-base * 1.75;
|
|
12
|
-
$h3-font-size: $headings-font-size-base * 1.5;
|
|
13
|
-
$h4-font-size: $headings-font-size-base * 1.25;
|
|
14
|
-
$h5-font-size: $headings-font-size-base * 1.125;
|
|
15
|
-
$h6-font-size: $headings-font-size-base;
|
|
16
|
-
|
|
17
|
-
$zindex-toaster: 1071 !default;
|
|
18
|
-
|
|
19
|
-
$border-radius: .5rem;
|
|
20
|
-
$border-radius-sm: .375rem;
|
|
21
|
-
$border-radius-lg: .75rem;
|
|
22
|
-
|
|
23
|
-
$project-tnm: #311b92;
|
|
24
|
-
$project-fixed: #388E3C;
|
|
25
|
-
$project-nonprofit: #D32F2F;
|
|
26
|
-
|
|
27
|
-
$info: #5981c0;
|
|
28
|
-
$success: #10834e;
|
|
29
|
-
$warning: #cda277;
|
|
30
|
-
$danger: #cb4839;
|
|
31
|
-
|
|
32
|
-
$primary: #0B314F;
|
|
33
|
-
$link-color: #0B314F;
|
|
34
|
-
$input-btn-focus-width: .125rem;
|
|
35
|
-
|
|
36
|
-
$input-bg: #f3f3f3;
|
|
37
|
-
$input-border-color: rgba(#000, .08);
|
|
38
|
-
$input-border-radius: 10px;
|
|
39
|
-
$input-font-size: 0.875rem;
|
|
40
|
-
$input-font-family: "Fira Mono", "Courier New", monospace;
|
|
41
|
-
|
|
42
|
-
$input-focus-bg: #fff;
|
|
43
|
-
$input-focus-border-color: #fff;
|
|
44
|
-
|
|
45
|
-
$form-label-margin-bottom: .1rem;
|
|
46
|
-
$input-focus-border: rgb(11 49 79 / 25%);
|
|
47
|
-
|
|
48
|
-
$form-check-input-border: 1px solid rgba(#000, .08);
|
|
49
|
-
$form-switch-focus-color: tint-color($primary, 50%);
|
|
50
|
-
|
|
51
|
-
$modal-backdrop-bg: #999;
|
|
52
|
-
$modal-backdrop-opacity: .25;
|
|
53
|
-
$modal-content-border-radius: 0;
|
|
54
|
-
|
|
55
|
-
$secondary: #dfe1e6;
|
|
56
|
-
|
|
57
|
-
// popover
|
|
58
|
-
$popover-border-width: 2px;
|
|
59
|
-
|
|
60
|
-
// dropdown
|
|
61
|
-
|
|
62
|
-
// Dark theme
|
|
63
|
-
$dark-body-bg: #2e3136;
|
|
64
|
-
$dark-border-color: #4a4a4a;
|
|
65
|
-
$dark-body-color: #ddd;
|
|
66
|
-
$dark-input-bg: #383b41;
|
|
67
|
-
|
|
68
|
-
$dark-primary: #FFCC00;
|
|
69
|
-
$dark-link-color: #ead272;
|
|
70
|
-
$dark-secondary: #464a53;
|
|
71
|
-
$dark-input-focus-border-color: #3d3d3d;
|
|
72
|
-
$dark-btn-primary-color: $dark-primary;
|
|
73
|
-
$dark-btn-secondary-color: $dark-secondary;
|
|
74
|
-
$dark-input-box-shadow: #3d3d3d;
|
|
75
|
-
$dark-input-focus-border: rgb(244 206 176 / 25%);
|
|
76
|
-
|
|
77
|
-
$pagination-border-width: 0;
|
|
78
|
-
|
|
79
|
-
// 3. Include remainder of required Bootstrap stylesheets
|
|
80
|
-
@import "~bootstrap/scss/variables.scss";
|
|
81
|
-
@import "~bootstrap/scss/mixins.scss";
|
|
82
|
-
@import "~bootstrap/scss/maps.scss";
|
|
83
|
-
@import "~bootstrap/scss/utilities.scss";
|
|
84
|
-
|
|
85
|
-
$custom-colors: (
|
|
86
|
-
"white": #fff,
|
|
87
|
-
"black": #1e1e1e
|
|
88
|
-
);
|
|
89
|
-
$theme-colors: map-merge($theme-colors, $custom-colors);
|
|
90
|
-
|
|
91
|
-
// Text colors
|
|
92
|
-
$all-colors: map-merge-multiple($theme-colors, $custom-colors, $blues, $indigos, $purples, $pinks, $reds, $oranges, $yellows, $greens, $teals, $cyans);
|
|
93
|
-
$utilities: map-merge(
|
|
94
|
-
$utilities,
|
|
95
|
-
(
|
|
96
|
-
"color": map-merge(
|
|
97
|
-
map-get($utilities, "color"),
|
|
98
|
-
(
|
|
99
|
-
values: map-merge(
|
|
100
|
-
map-get(map-get($utilities, "color"), "values"),
|
|
101
|
-
(
|
|
102
|
-
$all-colors
|
|
103
|
-
),
|
|
104
|
-
),
|
|
105
|
-
),
|
|
106
|
-
),
|
|
107
|
-
)
|
|
108
|
-
);
|
|
109
|
-
@import "~bootstrap/scss/utilities/api";
|
|
110
|
-
|
|
111
|
-
// Fonts
|
|
112
|
-
$baseFontSize: 16px;
|
|
113
|
-
$hintFontSize: 12px;
|
|
114
|
-
|
|
115
|
-
// Border radius
|
|
116
|
-
$borderRadiusM: 4px;
|
|
117
|
-
$borderRadiusL: 8px;
|
|
118
|
-
|
|
119
|
-
// Colors
|
|
120
|
-
$primaryColor: #0B314F;
|
|
121
|
-
$primaryColor15: #DAE0E5;
|
|
122
|
-
$baseText: #1e1e1e;
|
|
123
|
-
$gray5: #F0F0F1;
|
|
124
|
-
$gray50: #787885;
|