gnui 1.2.17 → 1.2.19
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/dist/js/gnui.esm.js +736 -96
- package/dist/js/gnui.js +736 -96
- package/dist/js/gnui.min.js +6 -6
- package/dist/styles/default.css +1019 -108
- package/dist/styles/gpi.css +1019 -108
- package/dist/styles/green24.css +1230 -289
- package/dist/styles/insights.css +1019 -108
- package/dist/styles/nac.css +969 -58
- package/dist/styles/ztnac.css +1206 -265
- package/package.json +1 -1
- package/styleguide/assets/components.js +216 -9
- package/styleguide/assets/js/gnui.js +736 -96
- package/styleguide/assets/js/gnui.min.js +6 -6
- package/styleguide/assets/styles/default.css +1019 -108
- package/styleguide/assets/styles/gpi.css +1019 -108
- package/styleguide/assets/styles/green24.css +1230 -289
- package/styleguide/assets/styles/insights.css +1019 -108
- package/styleguide/assets/styles/nac.css +969 -58
- package/styleguide/assets/styles/ztnac.css +1206 -265
- package/styleguide/category/COLOR/index.html +2 -2
- package/styleguide/category/COMPONENT/Alert(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Bignumber/index.html +2 -2
- package/styleguide/category/COMPONENT/Breadcrumb/index.html +2 -2
- package/styleguide/category/COMPONENT/Calendar(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Card/index.html +2 -2
- package/styleguide/category/COMPONENT/Chart(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Datagrid(js)/index.html +136 -9
- package/styleguide/category/COMPONENT/Datalist(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Growl(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/JsonView(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Loader(js)/index.html +21 -4
- package/styleguide/category/COMPONENT/MenuButton(js)/index.html +74 -6
- package/styleguide/category/COMPONENT/Message(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Modal(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Pagination(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Panel/index.html +2 -2
- package/styleguide/category/COMPONENT/Progressbar(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Tab(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Tagcloud(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Tooltip(js)/index.html +2 -2
- package/styleguide/category/COMPONENT/Tree(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/Button(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/Checkbox/index.html +2 -2
- package/styleguide/category/CONTROLS/Colorpicker(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/Datepicker(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/Dropdown(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/File/index.html +2 -2
- package/styleguide/category/CONTROLS/Form/Control/index.html +2 -2
- package/styleguide/category/CONTROLS/Form/Field/index.html +2 -2
- package/styleguide/category/CONTROLS/Form/Plain/index.html +2 -2
- package/styleguide/category/CONTROLS/Input/index.html +2 -2
- package/styleguide/category/CONTROLS/MultiText(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/Picklist(js)/index.html +28 -18
- package/styleguide/category/CONTROLS/Radio/index.html +2 -2
- package/styleguide/category/CONTROLS/Select/index.html +2 -2
- package/styleguide/category/CONTROLS/SelectButton(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/Slider/index.html +2 -2
- package/styleguide/category/CONTROLS/SortableList(js)/index.html +487 -0
- package/styleguide/category/CONTROLS/Switch(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/SyntaxInput(js)/index.html +2 -2
- package/styleguide/category/CONTROLS/Textarea/index.html +2 -2
- package/styleguide/category/CONTROLS/Time(js)/index.html +2 -2
- package/styleguide/category/ELEMENTS/Box/index.html +2 -2
- package/styleguide/category/ELEMENTS/Icon/index.html +2 -2
- package/styleguide/category/ELEMENTS/Image/index.html +2 -2
- package/styleguide/category/ELEMENTS/List/index.html +2 -2
- package/styleguide/category/ELEMENTS/Table/index.html +2 -2
- package/styleguide/category/ELEMENTS/Tag/index.html +2 -2
- package/styleguide/category/ELEMENTS/Title/index.html +2 -2
- package/styleguide/category/LAYOUT/Container/index.html +2 -2
- package/styleguide/category/LAYOUT/Grid/index.html +2 -2
- package/styleguide/category/LAYOUT/Splitter(js)/index.html +2 -2
- package/styleguide/category/UTILITY/index.html +2 -2
- package/styleguide/category/Utils/index.html +2 -2
- package/styleguide/color.html +2 -2
- package/styleguide/index.html +2 -2
- package/styleguide/tag/javascript/index.html +608 -31
- package/styleguide/tag/v.0.1.0/index.html +608 -31
package/dist/js/gnui.esm.js
CHANGED
|
@@ -16924,7 +16924,10 @@ class GNCoreEventManager {
|
|
|
16924
16924
|
// 이벤트 삭제
|
|
16925
16925
|
delete this._eventMap[uid];
|
|
16926
16926
|
}
|
|
16927
|
-
|
|
16927
|
+
/**
|
|
16928
|
+
* lifeCycle 핸들러 실행
|
|
16929
|
+
*/
|
|
16930
|
+
cyclepatch(uid, name, params) {
|
|
16928
16931
|
const _events = this._getEvent(uid, name);
|
|
16929
16932
|
if (_events.length) {
|
|
16930
16933
|
_events.forEach((_event) => {
|
|
@@ -16933,6 +16936,28 @@ class GNCoreEventManager {
|
|
|
16933
16936
|
});
|
|
16934
16937
|
}
|
|
16935
16938
|
}
|
|
16939
|
+
/**
|
|
16940
|
+
* 등록된 이벤트 핸들러 실행
|
|
16941
|
+
*
|
|
16942
|
+
* - sync/async 핸들러를 모두 지원한다.
|
|
16943
|
+
* - 모든 핸들러를 순차 실행한 뒤, 하나라도 `false` 를 반환한 경우 `true`(cancelled)를 반환한다.
|
|
16944
|
+
* (첫 false 에서 중단하지 않고, 나머지 핸들러도 계속 실행한다)
|
|
16945
|
+
*/
|
|
16946
|
+
async dispatch(uid, name, params) {
|
|
16947
|
+
const _events = this._getEvent(uid, name);
|
|
16948
|
+
let cancelled = false;
|
|
16949
|
+
if (_events.length) {
|
|
16950
|
+
for (const _event of _events) {
|
|
16951
|
+
const _target = _event.target || this;
|
|
16952
|
+
// sync/async 둘 다 지원: Promise.resolve 로 감싸서 await
|
|
16953
|
+
const result = await Promise.resolve(params ? _event.handler.call(_target, ...params) : _event.handler.call(_target));
|
|
16954
|
+
if (result === false) {
|
|
16955
|
+
cancelled = true;
|
|
16956
|
+
}
|
|
16957
|
+
}
|
|
16958
|
+
}
|
|
16959
|
+
return cancelled;
|
|
16960
|
+
}
|
|
16936
16961
|
_getEvent(uid, name) {
|
|
16937
16962
|
// parameters에 해당하는 이벤트 반환
|
|
16938
16963
|
return this._eventMap[uid]
|
|
@@ -17017,7 +17042,7 @@ class GNUIState {
|
|
|
17017
17042
|
});
|
|
17018
17043
|
return _findComponent;
|
|
17019
17044
|
}
|
|
17020
|
-
// 등록된 컴포넌트 제거
|
|
17045
|
+
// 등록된 컴포넌트 제거 (selector 기반)
|
|
17021
17046
|
_removeComponent(selector) {
|
|
17022
17047
|
if (!selector) {
|
|
17023
17048
|
return;
|
|
@@ -17026,10 +17051,30 @@ class GNUIState {
|
|
|
17026
17051
|
Object.values(this._componentMap).forEach(n => {
|
|
17027
17052
|
// 동일한 selector 인지 비교해서 동일한 component의 selector이면 제거 처리
|
|
17028
17053
|
if (isEquals(n.selector, _selector)) {
|
|
17029
|
-
|
|
17054
|
+
// componentMap에서 완전히 제거
|
|
17055
|
+
delete this._componentMap[n.uid];
|
|
17056
|
+
// 컴포넌트 내부 참조도 제거 (메모리 누수 방지)
|
|
17057
|
+
if (n.component) {
|
|
17058
|
+
n.component = null;
|
|
17059
|
+
}
|
|
17060
|
+
n.selector = null;
|
|
17030
17061
|
}
|
|
17031
17062
|
});
|
|
17032
17063
|
}
|
|
17064
|
+
// 등록된 컴포넌트 제거 (uid 기반 - 더 효율적)
|
|
17065
|
+
_removeComponentByUid(uid) {
|
|
17066
|
+
if (!uid || !this._componentMap[uid]) {
|
|
17067
|
+
return;
|
|
17068
|
+
}
|
|
17069
|
+
// 컴포넌트 내부 참조 제거 (메모리 누수 방지)
|
|
17070
|
+
const componentInfo = this._componentMap[uid];
|
|
17071
|
+
if (componentInfo.component) {
|
|
17072
|
+
componentInfo.component = null;
|
|
17073
|
+
}
|
|
17074
|
+
componentInfo.selector = null;
|
|
17075
|
+
// componentMap에서 완전히 제거
|
|
17076
|
+
delete this._componentMap[uid];
|
|
17077
|
+
}
|
|
17033
17078
|
// 컴포넌트 life cycle에 따른 eventManager dispatch
|
|
17034
17079
|
_detectedCycle(uid, name) {
|
|
17035
17080
|
// component 마지막 status 업데이트
|
|
@@ -17039,7 +17084,7 @@ class GNUIState {
|
|
|
17039
17084
|
// event manager를 이용해 해당 uid 이벤트 dispatch
|
|
17040
17085
|
const eventManager = GNCoreEventManager.getInstance();
|
|
17041
17086
|
// 호출 후
|
|
17042
|
-
eventManager.
|
|
17087
|
+
eventManager.cyclepatch(uid, name, '');
|
|
17043
17088
|
// 이벤트 해제 - life cycle 은 컴포넌트 별로 한번씩만 존재하므로..
|
|
17044
17089
|
eventManager.remove(uid, name);
|
|
17045
17090
|
}
|
|
@@ -17053,6 +17098,7 @@ class GNUIState {
|
|
|
17053
17098
|
function _removedNode(removed) {
|
|
17054
17099
|
Array.prototype.forEach.call(removed, (rm) => {
|
|
17055
17100
|
// 삭제노드 연관 컴포넌트 (ex. tooltip) 삭제
|
|
17101
|
+
var _a;
|
|
17056
17102
|
const dependents = findAll('[data-gnui]', rm);
|
|
17057
17103
|
each(dependents, (dependent) => {
|
|
17058
17104
|
if (isElement$2(dependent)) {
|
|
@@ -17065,12 +17111,19 @@ class GNUIState {
|
|
|
17065
17111
|
if (isElement$2(rm) && attr(rm, 'data-gnui')) {
|
|
17066
17112
|
remove($('#' + attr(rm, 'data-gnui')));
|
|
17067
17113
|
}
|
|
17114
|
+
const childComponents = $$('[data-gn-uid]', rm);
|
|
17115
|
+
each(childComponents, (childComponent) => {
|
|
17116
|
+
if (isElement$2(childComponent)) {
|
|
17117
|
+
const findComponent = closerThis._getComponent($(childComponent));
|
|
17118
|
+
if (findComponent && findComponent._uid && findComponent.$el && findComponent.$name !== 'modal') {
|
|
17119
|
+
// $destroy 내부에서 removeAll과 _removeComponentByUid를 처리하므로 직접 호출만
|
|
17120
|
+
findComponent.$destroy(findComponent, false);
|
|
17121
|
+
}
|
|
17122
|
+
}
|
|
17123
|
+
});
|
|
17068
17124
|
const findComponent = closerThis._getComponent($(rm));
|
|
17069
|
-
if (findComponent && findComponent._uid && !findComponent.$el.parentNode && findComponent.$name !== 'modal') {
|
|
17070
|
-
|
|
17071
|
-
closerThis._removeComponent(rm);
|
|
17072
|
-
// event manager 에서 unbind
|
|
17073
|
-
GNCoreEventManager.getInstance().removeAll(findComponent._uid);
|
|
17125
|
+
if (findComponent && findComponent._uid && !((_a = findComponent.$el) === null || _a === void 0 ? void 0 : _a.parentNode) && findComponent.$name !== 'modal') {
|
|
17126
|
+
findComponent.$destroy(findComponent, false);
|
|
17074
17127
|
}
|
|
17075
17128
|
});
|
|
17076
17129
|
}
|
|
@@ -17226,6 +17279,7 @@ class GNCoreInstance {
|
|
|
17226
17279
|
if (tmpRole) {
|
|
17227
17280
|
attr(this.$el, 'role', tmpRole);
|
|
17228
17281
|
}
|
|
17282
|
+
attr(this.$el, 'data-gn-uid', this._uid);
|
|
17229
17283
|
// inherit selector class
|
|
17230
17284
|
selector.className && addClass(this.$el, selector.className);
|
|
17231
17285
|
}
|
|
@@ -17265,25 +17319,48 @@ class GNCoreInstance {
|
|
|
17265
17319
|
}
|
|
17266
17320
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17267
17321
|
$update(element = this.$el, e) { }
|
|
17268
|
-
|
|
17322
|
+
/**
|
|
17323
|
+
* 컴포넌트 이벤트 디스패치 헬퍼
|
|
17324
|
+
*
|
|
17325
|
+
* - sync/async 핸들러 모두 지원한다.
|
|
17326
|
+
* - 하나 이상의 핸들러에서 `false`를 반환하면 `true`(cancelled) 를 반환한다.
|
|
17327
|
+
* - 단순 알림용(fire-and-forget) 이벤트는 반환값/await 없이 호출해도 된다.
|
|
17328
|
+
*/
|
|
17329
|
+
async $event(component, name, ...params) {
|
|
17269
17330
|
const eventManager = GNCoreEventManager.getInstance();
|
|
17270
|
-
eventManager.dispatch(component._uid, name, params);
|
|
17331
|
+
return eventManager.dispatch(component._uid, name, params);
|
|
17271
17332
|
}
|
|
17272
17333
|
$destroy(component = this, removeEl = true) {
|
|
17334
|
+
var _a;
|
|
17273
17335
|
const stateManager = GNUIState.getInstance();
|
|
17274
17336
|
// state manager 를 통해 destroy 상태 dispatch
|
|
17275
17337
|
stateManager._detectedCycle(component._uid, 'destroy');
|
|
17276
|
-
// remove Component in state manager
|
|
17277
|
-
stateManager._removeComponent(component.$selector);
|
|
17278
17338
|
// remove DOM (by removeEl)
|
|
17279
17339
|
if (removeEl) {
|
|
17280
17340
|
style(component.$el, 'display', 'none');
|
|
17281
17341
|
remove(component.$el);
|
|
17282
17342
|
}
|
|
17343
|
+
if (((_a = component.$options) === null || _a === void 0 ? void 0 : _a._destroy) && isFunction(component.$options._destroy)) {
|
|
17344
|
+
component.$options._destroy();
|
|
17345
|
+
}
|
|
17283
17346
|
// state manager 를 통해 destroy 상태 dispatch
|
|
17284
17347
|
stateManager._detectedCycle(component._uid, 'destroyed');
|
|
17285
|
-
// event manager 에서 등록
|
|
17348
|
+
// event manager 에서 등록 해제
|
|
17286
17349
|
GNCoreEventManager.getInstance().removeAll(component._uid);
|
|
17350
|
+
// state manager에서 component 제거 (uid 기반으로 효율적 제거)
|
|
17351
|
+
stateManager._removeComponentByUid(component._uid);
|
|
17352
|
+
// 메모리 누수 방지: component의 모든 hasOwnProperty 제거
|
|
17353
|
+
// config, events, methods, _hidden 등 동적으로 추가된 속성 포함
|
|
17354
|
+
Object.keys(component).forEach((key) => {
|
|
17355
|
+
try {
|
|
17356
|
+
component[key] = null;
|
|
17357
|
+
delete component[key];
|
|
17358
|
+
}
|
|
17359
|
+
catch (e) {
|
|
17360
|
+
// readonly 속성 등 삭제 불가능한 경우 무시
|
|
17361
|
+
}
|
|
17362
|
+
});
|
|
17363
|
+
component = null;
|
|
17287
17364
|
}
|
|
17288
17365
|
}
|
|
17289
17366
|
|
|
@@ -33484,8 +33561,19 @@ class Dropdown extends GNCoreInstance {
|
|
|
33484
33561
|
});
|
|
33485
33562
|
if (this.$options.value) {
|
|
33486
33563
|
if (this.$options.multiple) {
|
|
33487
|
-
|
|
33488
|
-
|
|
33564
|
+
// multiple 모드에서 다양한 타입의 value를 문자열 배열로 변환
|
|
33565
|
+
// 지원 타입: 문자열(쉼표 구분), 객체 배열, 단일 객체, 문자열 배열
|
|
33566
|
+
const values = typeof this.$options.value === 'string'
|
|
33567
|
+
? this.$options.value.split(',') // 케이스 1: 'item1,item2,item3'
|
|
33568
|
+
: Array.isArray(this.$options.value)
|
|
33569
|
+
? this.$options.value.map((v) => (typeof v === 'object' && v !== null && 'value' in v ? String(v.value) : String(v))) // 케이스 3: [{value:'item1', text:'항목1'}, ...] 또는 ['item1', 'item2']
|
|
33570
|
+
: typeof this.$options.value === 'object' && this.$options.value !== null && 'value' in this.$options.value
|
|
33571
|
+
? [String(this.$options.value.value)] // 케이스 2: {value:'item1', text:'항목1'}
|
|
33572
|
+
: [String(this.$options.value)]; // 기타: 숫자 등
|
|
33573
|
+
this.$options.value = this.$options.flatData.filter((opt) => {
|
|
33574
|
+
const optValue = typeof opt.value === 'string' ? opt.value : String(opt.value);
|
|
33575
|
+
return values.includes(optValue) && opt.text;
|
|
33576
|
+
});
|
|
33489
33577
|
}
|
|
33490
33578
|
else {
|
|
33491
33579
|
this.$options.value = this.$options.flatData.find((opt) => opt.value + '' === this.$options.value + '' && opt.text);
|
|
@@ -37000,26 +37088,8 @@ class DataGrid extends GNCoreInstance {
|
|
|
37000
37088
|
}
|
|
37001
37089
|
this.$event(this, 'onSort', column);
|
|
37002
37090
|
},
|
|
37003
|
-
renderHeader: (columns) => {
|
|
37004
|
-
this
|
|
37005
|
-
!this.$options.readonly &&
|
|
37006
|
-
columns.push({
|
|
37007
|
-
label: this.$options.textSets.orderLabel,
|
|
37008
|
-
key: 'btnOrder',
|
|
37009
|
-
style: {
|
|
37010
|
-
width: '50px'
|
|
37011
|
-
}
|
|
37012
|
-
});
|
|
37013
|
-
this.$options.hasDelete &&
|
|
37014
|
-
!this.$options.readonly &&
|
|
37015
|
-
columns.push({
|
|
37016
|
-
label: this.$options.textSets.deleteLabel,
|
|
37017
|
-
key: 'btnDelete',
|
|
37018
|
-
style: {
|
|
37019
|
-
width: '30px'
|
|
37020
|
-
}
|
|
37021
|
-
});
|
|
37022
|
-
this._setColumnsTemplate();
|
|
37091
|
+
renderHeader: (columns, isReset = false) => {
|
|
37092
|
+
this._setColumnsTemplate(isReset);
|
|
37023
37093
|
return (createElement$1("div", { className: "gn-datagrid-header-row", style: {
|
|
37024
37094
|
'grid-template-columns': this._columnsTemplate.join(' ')
|
|
37025
37095
|
} },
|
|
@@ -37058,6 +37128,10 @@ class DataGrid extends GNCoreInstance {
|
|
|
37058
37128
|
column.draggable && (this.$options.headers ? idx < this.$options.headers.length - 1 : true) && createElement$1("span", { className: "is-handle", "data-index": idx })));
|
|
37059
37129
|
},
|
|
37060
37130
|
renderBody: (data, columns) => {
|
|
37131
|
+
// 헤더가 숨겨진 경우에도 body 렌더 전에 템플릿 폭을 준비한다
|
|
37132
|
+
if (!this._columnsTemplate || !this._columnsTemplate.length) {
|
|
37133
|
+
this._setColumnsTemplate();
|
|
37134
|
+
}
|
|
37061
37135
|
rowIdx$1 = 0;
|
|
37062
37136
|
return (createElement$1("div", { className: "gn-datagrid-body", style: {
|
|
37063
37137
|
maxHeight: this.$options.bodyHeight ? this.$options.bodyHeight : 'auto'
|
|
@@ -37071,7 +37145,6 @@ class DataGrid extends GNCoreInstance {
|
|
|
37071
37145
|
});
|
|
37072
37146
|
},
|
|
37073
37147
|
renderRow: (row, columns, depth = 0, hasChild, isOpened, isCheck = false) => {
|
|
37074
|
-
row._depth = depth;
|
|
37075
37148
|
const _index = rowIdx$1++;
|
|
37076
37149
|
if (row.isChecked) {
|
|
37077
37150
|
isCheck = true;
|
|
@@ -37205,8 +37278,9 @@ class DataGrid extends GNCoreInstance {
|
|
|
37205
37278
|
e.stopPropagation();
|
|
37206
37279
|
toggler = parents(e.currentTarget, '.gn-datagrid-body-row');
|
|
37207
37280
|
}
|
|
37208
|
-
const
|
|
37209
|
-
|
|
37281
|
+
const rowDepth = Number(attr(toggler, 'data-depth')) || 0;
|
|
37282
|
+
const children = nextUntil(toggler, '.gn-datagrid-body-row[data-depth="' + rowDepth + '"]').filter((x) => {
|
|
37283
|
+
return Number(attr(x, 'data-depth')) > rowDepth;
|
|
37210
37284
|
});
|
|
37211
37285
|
type = type ? type : hasClass(toggler, 'is-collapsed') ? 'expand' : 'collapse';
|
|
37212
37286
|
if (type === 'collapse') {
|
|
@@ -37222,7 +37296,7 @@ class DataGrid extends GNCoreInstance {
|
|
|
37222
37296
|
//show childs
|
|
37223
37297
|
removeClass(toggler, 'is-collapsed');
|
|
37224
37298
|
removeClass(children.filter((x) => {
|
|
37225
|
-
return x
|
|
37299
|
+
return Number(attr(x, 'data-depth')) == rowDepth + 1;
|
|
37226
37300
|
}), 'is-hidden');
|
|
37227
37301
|
this.$event(this, 'onToggle', 'expanded', row, index$1(toggler));
|
|
37228
37302
|
}
|
|
@@ -37280,13 +37354,15 @@ class DataGrid extends GNCoreInstance {
|
|
|
37280
37354
|
e.stopPropagation();
|
|
37281
37355
|
const checker = parents(e.currentTarget, '.gn-datagrid-body-row');
|
|
37282
37356
|
const checkerState = e.target.checked;
|
|
37283
|
-
find('.is-allChecker', this.$el)
|
|
37357
|
+
const allChecker = find('.is-allChecker', this.$el);
|
|
37358
|
+
allChecker && (allChecker.checked = false);
|
|
37359
|
+
const rowDepth = Number(attr(checker, 'data-depth')) || 0;
|
|
37284
37360
|
// 1. row에 자식노드가 있는지 확인한다.
|
|
37285
37361
|
if (this.$options.checkCapturing && row[this.$options.childField] && row[this.$options.childField].length) {
|
|
37286
37362
|
// 2. 자식노드가 있는경우 자식 체크박스도 함께 토글한다.
|
|
37287
|
-
nextUntil(checker, '.gn-datagrid-body-row[data-depth="' +
|
|
37363
|
+
nextUntil(checker, '.gn-datagrid-body-row[data-depth="' + rowDepth + '"]')
|
|
37288
37364
|
.filter((x) => {
|
|
37289
|
-
return x
|
|
37365
|
+
return Number(attr(x, 'data-depth')) > rowDepth;
|
|
37290
37366
|
})
|
|
37291
37367
|
.forEach((x) => {
|
|
37292
37368
|
const _checker = find('.is-rowChecker', x);
|
|
@@ -37296,17 +37372,17 @@ class DataGrid extends GNCoreInstance {
|
|
|
37296
37372
|
});
|
|
37297
37373
|
}
|
|
37298
37374
|
// 3. 체크 해제인 경우만 부모노드가 있는지 확인한다.
|
|
37299
|
-
if (this.$options.checkCapturing &&
|
|
37375
|
+
if (this.$options.checkCapturing && rowDepth > 0 && !checkerState) {
|
|
37300
37376
|
// 4. 부모노드가 체크되어 있는지 확인한다
|
|
37301
37377
|
const exeDepth = [];
|
|
37302
37378
|
prevUntil(checker, '.gn-datagrid-body-row[data-depth="0"]')
|
|
37303
37379
|
.filter((x) => {
|
|
37304
|
-
const _thisDepth = x
|
|
37380
|
+
const _thisDepth = attr(x, 'data-depth');
|
|
37305
37381
|
if (exeDepth.includes(_thisDepth)) {
|
|
37306
37382
|
return false;
|
|
37307
37383
|
}
|
|
37308
37384
|
exeDepth.push(_thisDepth);
|
|
37309
|
-
return _thisDepth <
|
|
37385
|
+
return Number(_thisDepth) < rowDepth;
|
|
37310
37386
|
})
|
|
37311
37387
|
.forEach((x) => {
|
|
37312
37388
|
const _checker = find('.is-rowChecker', x);
|
|
@@ -37322,9 +37398,21 @@ class DataGrid extends GNCoreInstance {
|
|
|
37322
37398
|
if (hasCheck === undefined) {
|
|
37323
37399
|
hasCheck = this.$options.hasCheck;
|
|
37324
37400
|
}
|
|
37325
|
-
this.$options.headers
|
|
37401
|
+
const prevHeaders = [...(this.$options.headers || [])];
|
|
37402
|
+
// _prepareHeaders가 배열을 변경하므로 비교용(prevHeaders)과 가공용(baseHeaders)을 분리한다
|
|
37403
|
+
const baseHeaders = headers ? [...headers] : [...prevHeaders];
|
|
37404
|
+
const preparedHeaders = this._prepareHeaders(baseHeaders);
|
|
37405
|
+
// 헤더 배열의 내용(길이, key)이 바뀐 경우에만 DOM 기반 폭 계산을 리셋한다
|
|
37406
|
+
const isReset = prevHeaders.length !== preparedHeaders.length || prevHeaders.some((header, idx) => { var _a; return header.key !== ((_a = preparedHeaders[idx]) === null || _a === void 0 ? void 0 : _a.key); });
|
|
37326
37407
|
this.$options.hasCheck = hasCheck;
|
|
37327
|
-
|
|
37408
|
+
const headerRow = find('.gn-datagrid-header-row', this.$el);
|
|
37409
|
+
// 헤더가 없을 때도 컬럼 수/폭 변경을 반영하기 위해 템플릿을 갱신한다
|
|
37410
|
+
if (this.$options.hasHeader && headerRow) {
|
|
37411
|
+
this.$template.reRender(headerRow, this._hidden.renderHeader(preparedHeaders, isReset));
|
|
37412
|
+
}
|
|
37413
|
+
else {
|
|
37414
|
+
this._setColumnsTemplate(isReset);
|
|
37415
|
+
}
|
|
37328
37416
|
this._hidden.resetData(data ? arrClone(data) : this.$options.data);
|
|
37329
37417
|
this.$render(this.$options);
|
|
37330
37418
|
isFunction(resolve) && resolve();
|
|
@@ -37339,6 +37427,10 @@ class DataGrid extends GNCoreInstance {
|
|
|
37339
37427
|
});
|
|
37340
37428
|
},
|
|
37341
37429
|
awaitData: (data) => {
|
|
37430
|
+
// asyncData 콜백 실행 중 컴포넌트가 destroy된 경우 안전하게 종료
|
|
37431
|
+
if (!this.$options || !this._hidden) {
|
|
37432
|
+
return;
|
|
37433
|
+
}
|
|
37342
37434
|
if (this.$options.asyncData && this.$options.paginator && !this._paginator) {
|
|
37343
37435
|
this._paginator = new Pagination('pagination', find('.gn-datagrid-footer', this.$el), {
|
|
37344
37436
|
total: this.$options.paginator.total || 0,
|
|
@@ -37363,7 +37455,8 @@ class DataGrid extends GNCoreInstance {
|
|
|
37363
37455
|
this._fixCellStyleOnDraggable();
|
|
37364
37456
|
// 체크박스가 있는경우 전체 체크항목을 해제해준다
|
|
37365
37457
|
if (this.$options.hasCheck) {
|
|
37366
|
-
find('.is-allChecker', this.$el)
|
|
37458
|
+
const allChecker = find('.is-allChecker', this.$el);
|
|
37459
|
+
allChecker && (allChecker.checked = false);
|
|
37367
37460
|
}
|
|
37368
37461
|
isFunction(resolve) && resolve();
|
|
37369
37462
|
});
|
|
@@ -37398,8 +37491,18 @@ class DataGrid extends GNCoreInstance {
|
|
|
37398
37491
|
stopRowSelectEvent: (e) => {
|
|
37399
37492
|
e.stopPropagation();
|
|
37400
37493
|
},
|
|
37401
|
-
deleteRow: (index) => {
|
|
37402
|
-
|
|
37494
|
+
deleteRow: async (index) => {
|
|
37495
|
+
var _a;
|
|
37496
|
+
const confirmMessage = (_a = this.$options.textSets) === null || _a === void 0 ? void 0 : _a.deleteConfirmMessage;
|
|
37497
|
+
if (confirmMessage && !window.confirm(confirmMessage)) {
|
|
37498
|
+
return;
|
|
37499
|
+
}
|
|
37500
|
+
const removedData = this._hidden.findData(index);
|
|
37501
|
+
const cancelled = await this.$event(this, 'onDelete', removedData, index);
|
|
37502
|
+
if (cancelled) {
|
|
37503
|
+
return;
|
|
37504
|
+
}
|
|
37505
|
+
this._hidden.deleteData(index);
|
|
37403
37506
|
this._hidden.resetData(this.$options.data);
|
|
37404
37507
|
this.$event(this, 'onChange', this.$options.data);
|
|
37405
37508
|
},
|
|
@@ -37434,22 +37537,38 @@ class DataGrid extends GNCoreInstance {
|
|
|
37434
37537
|
col.offHover && col.offHover.call(this, row, col, index, e);
|
|
37435
37538
|
},
|
|
37436
37539
|
findData: (index) => {
|
|
37437
|
-
|
|
37438
|
-
|
|
37439
|
-
|
|
37440
|
-
|
|
37441
|
-
|
|
37540
|
+
return this._hidden.walkByIndex(index, 'find');
|
|
37541
|
+
},
|
|
37542
|
+
deleteData: (index) => {
|
|
37543
|
+
return this._hidden.walkByIndex(index, 'delete');
|
|
37544
|
+
},
|
|
37545
|
+
walkByIndex: (index, action) => {
|
|
37546
|
+
let deter = 0;
|
|
37547
|
+
let result = null;
|
|
37548
|
+
const findIndex = (datas) => {
|
|
37549
|
+
for (let i = 0; i < datas.length; i++) {
|
|
37550
|
+
if (deter === index) {
|
|
37551
|
+
switch (action) {
|
|
37552
|
+
case 'find':
|
|
37553
|
+
result = datas[i];
|
|
37554
|
+
break;
|
|
37555
|
+
case 'delete':
|
|
37556
|
+
result = datas.splice(i, 1)[0];
|
|
37557
|
+
break;
|
|
37558
|
+
}
|
|
37442
37559
|
return true;
|
|
37443
37560
|
}
|
|
37444
|
-
|
|
37445
|
-
|
|
37446
|
-
|
|
37561
|
+
deter++;
|
|
37562
|
+
const children = datas[i][this.$options.childField];
|
|
37563
|
+
if (Array.isArray(children) && children.length) {
|
|
37564
|
+
if (findIndex(children))
|
|
37565
|
+
return true;
|
|
37447
37566
|
}
|
|
37448
|
-
|
|
37449
|
-
|
|
37567
|
+
}
|
|
37568
|
+
return false;
|
|
37450
37569
|
};
|
|
37451
|
-
findIndex(this.$options.data
|
|
37452
|
-
return
|
|
37570
|
+
findIndex(this.$options.data);
|
|
37571
|
+
return result;
|
|
37453
37572
|
},
|
|
37454
37573
|
getChecked: () => {
|
|
37455
37574
|
return findAll('.is-rowChecker', this.$el)
|
|
@@ -37536,11 +37655,13 @@ class DataGrid extends GNCoreInstance {
|
|
|
37536
37655
|
hasOrder: false,
|
|
37537
37656
|
hasDelete: false,
|
|
37538
37657
|
isEllipsis: false,
|
|
37658
|
+
hasHeader: true,
|
|
37539
37659
|
data: [],
|
|
37540
37660
|
textSets: {
|
|
37541
37661
|
noData: 'No records available.',
|
|
37542
37662
|
orderLabel: '',
|
|
37543
|
-
deleteLabel: ''
|
|
37663
|
+
deleteLabel: '',
|
|
37664
|
+
deleteConfirmMessage: ''
|
|
37544
37665
|
},
|
|
37545
37666
|
childField: 'child',
|
|
37546
37667
|
checkCapturing: true,
|
|
@@ -37558,7 +37679,8 @@ class DataGrid extends GNCoreInstance {
|
|
|
37558
37679
|
onCheck: true,
|
|
37559
37680
|
onDoubleClick: true,
|
|
37560
37681
|
onChange: true,
|
|
37561
|
-
onDragEnd: true
|
|
37682
|
+
onDragEnd: true,
|
|
37683
|
+
onDelete: true
|
|
37562
37684
|
};
|
|
37563
37685
|
this.methods = {
|
|
37564
37686
|
reRender(options) {
|
|
@@ -37618,18 +37740,21 @@ class DataGrid extends GNCoreInstance {
|
|
|
37618
37740
|
this.$selector = this.$selector;
|
|
37619
37741
|
this.$init(this, options);
|
|
37620
37742
|
}
|
|
37621
|
-
_setColumnsTemplate() {
|
|
37743
|
+
_setColumnsTemplate(isReset = false) {
|
|
37622
37744
|
// header cell의 각 넓이를 배열로 가져온다
|
|
37623
37745
|
// ! 모든 컬럼의 넓이가 지정된 경우 이동(btnOrder), 삭제(btnDelete) 컬럼을 제외한 마지막 컬럼은 1fr로 고정
|
|
37624
37746
|
const _isfixedAllWidth = this.$options.headers.every((header) => { var _a; return ((_a = header.style) === null || _a === void 0 ? void 0 : _a.width) !== undefined; });
|
|
37625
37747
|
const _fixedTemplateColumn = this.$options.headers.findLast((header) => !this._isSystemAddedColumn(header.key) && !header.isHidden);
|
|
37748
|
+
// 헤더 DOM이 없거나 모든 일반 컬럼이 숨겨진 경우에도 안전하게 비교할 수 있도록 key만 옵셔널하게 캐싱한다
|
|
37749
|
+
const _fixedTemplateKey = _fixedTemplateColumn === null || _fixedTemplateColumn === void 0 ? void 0 : _fixedTemplateColumn.key;
|
|
37626
37750
|
const columns = findAll('.gn-datagrid-header-cell', this.$el);
|
|
37627
|
-
|
|
37751
|
+
// isReset이면 기존 DOM 폭을 재사용하지 않고 헤더 정의로 재계산
|
|
37752
|
+
if (this.$el && columns.length && !isReset) {
|
|
37628
37753
|
this._columnsTemplate = findAll('.gn-datagrid-header-cell', this.$el).map((header, idx) => {
|
|
37629
37754
|
if (this.$options.headers[idx].isHidden) {
|
|
37630
37755
|
return '';
|
|
37631
37756
|
}
|
|
37632
|
-
else if (_isfixedAllWidth && this.$options.headers[idx].key ===
|
|
37757
|
+
else if (_isfixedAllWidth && _fixedTemplateKey && this.$options.headers[idx].key === _fixedTemplateKey) {
|
|
37633
37758
|
return '1fr';
|
|
37634
37759
|
}
|
|
37635
37760
|
else {
|
|
@@ -37643,7 +37768,7 @@ class DataGrid extends GNCoreInstance {
|
|
|
37643
37768
|
if (header.isHidden) {
|
|
37644
37769
|
return '';
|
|
37645
37770
|
}
|
|
37646
|
-
else if (_isfixedAllWidth && header.key ===
|
|
37771
|
+
else if (_isfixedAllWidth && _fixedTemplateKey && header.key === _fixedTemplateKey) {
|
|
37647
37772
|
return '1fr';
|
|
37648
37773
|
}
|
|
37649
37774
|
else {
|
|
@@ -37664,18 +37789,45 @@ class DataGrid extends GNCoreInstance {
|
|
|
37664
37789
|
_isSystemAddedColumn(key) {
|
|
37665
37790
|
return ['btnOrder', 'btnDelete'].includes(key);
|
|
37666
37791
|
}
|
|
37792
|
+
// 옵션에 따른 추가 해더 구성
|
|
37793
|
+
_prepareHeaders(headers = []) {
|
|
37794
|
+
const hasOrderColumn = headers.some((header) => header.key === 'btnOrder');
|
|
37795
|
+
const hasDeleteColumn = headers.some((header) => header.key === 'btnDelete');
|
|
37796
|
+
if (this.$options.hasOrder && !this.$options.readonly && !hasOrderColumn) {
|
|
37797
|
+
headers.push({
|
|
37798
|
+
label: this.$options.textSets.orderLabel,
|
|
37799
|
+
key: 'btnOrder',
|
|
37800
|
+
style: {
|
|
37801
|
+
width: '50px'
|
|
37802
|
+
}
|
|
37803
|
+
});
|
|
37804
|
+
}
|
|
37805
|
+
if (this.$options.hasDelete && !this.$options.readonly && !hasDeleteColumn) {
|
|
37806
|
+
headers.push({
|
|
37807
|
+
label: this.$options.textSets.deleteLabel,
|
|
37808
|
+
key: 'btnDelete',
|
|
37809
|
+
style: {
|
|
37810
|
+
width: '30px'
|
|
37811
|
+
}
|
|
37812
|
+
});
|
|
37813
|
+
}
|
|
37814
|
+
this.$options.headers = headers;
|
|
37815
|
+
return headers;
|
|
37816
|
+
}
|
|
37667
37817
|
template(config) {
|
|
37668
37818
|
const styles = {};
|
|
37819
|
+
const headers = this._prepareHeaders(config.headers);
|
|
37669
37820
|
return (createElement$1("div", { id: this._uid, className: 'gn-datagrid' +
|
|
37670
37821
|
(config.style ? ' is-' + config.style : '') +
|
|
37671
37822
|
(config.isEllipsis ? ' is-ellipsis' : '') +
|
|
37672
37823
|
(config.bodyHeight ? ' has-fixed-body' : '') +
|
|
37673
37824
|
(config.fixHeader ? ' has-fixed-header' : '') +
|
|
37674
37825
|
(config.fixFooter ? ' has-fixed-footer' : '') +
|
|
37826
|
+
(!config.hasHeader ? ' is-headless' : '') +
|
|
37675
37827
|
(config.data.some((d) => isArray$1(d[this.$options.childField])) ? ' has-left-padding' : '') +
|
|
37676
37828
|
(config.disabled ? ' is-disabled' : ''), style: styles },
|
|
37677
|
-
createElement$1("div", { className: "gn-datagrid-header" }, this._hidden.renderHeader(
|
|
37678
|
-
createElement$1("div", { className: "gn-datagrid-contents", style: { marginTop: this.$options.bodyTopMargin ? this.$options.bodyTopMargin : '0', marginBottom: this.$options.bodyBottomMargin ? this.$options.bodyBottomMargin : '0' } }, this._hidden.renderBody(arrClone(config.data),
|
|
37829
|
+
config.hasHeader && createElement$1("div", { className: "gn-datagrid-header" }, this._hidden.renderHeader(headers)),
|
|
37830
|
+
createElement$1("div", { className: "gn-datagrid-contents", style: { marginTop: this.$options.bodyTopMargin ? this.$options.bodyTopMargin : '0', marginBottom: this.$options.bodyBottomMargin ? this.$options.bodyBottomMargin : '0' } }, this._hidden.renderBody(arrClone(config.data), headers)),
|
|
37679
37831
|
config.paginator /* 페이지네이터 옵션 확인 */ && createElement$1("div", { className: "gn-datagrid-footer" })));
|
|
37680
37832
|
}
|
|
37681
37833
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -37692,18 +37844,20 @@ class DataGrid extends GNCoreInstance {
|
|
|
37692
37844
|
}
|
|
37693
37845
|
}
|
|
37694
37846
|
completed() {
|
|
37695
|
-
if (this.$options.fixHeader) {
|
|
37847
|
+
if (this.$options.fixHeader && this.$options.hasHeader) {
|
|
37696
37848
|
const body = find('.gn-datagrid-contents', this.$el);
|
|
37697
37849
|
const header = find('.gn-datagrid-header', this.$el);
|
|
37698
|
-
|
|
37699
|
-
|
|
37700
|
-
|
|
37850
|
+
if (header) {
|
|
37851
|
+
const _offset = offset(header);
|
|
37852
|
+
this.$options.bodyTopMargin = _offset.height ? _offset.height - 1 + 'px' : '2.4rem';
|
|
37853
|
+
css$1(body, 'margin-top', this.$options.bodyTopMargin);
|
|
37854
|
+
}
|
|
37701
37855
|
if (this.$options.paginator) {
|
|
37702
37856
|
this.$options.bodyBottomMargin = '2.4rem';
|
|
37703
37857
|
css$1(body, 'margin-bottom', this.$options.bodyBottomMargin);
|
|
37704
37858
|
}
|
|
37705
37859
|
}
|
|
37706
|
-
if (this.$options.fixHeader || this.$options.bodyHeight) {
|
|
37860
|
+
if ((this.$options.fixHeader && this.$options.hasHeader) || this.$options.bodyHeight) {
|
|
37707
37861
|
this._hidden.setBlankHeader();
|
|
37708
37862
|
on(window, 'resize', this._hidden.setBlankHeader);
|
|
37709
37863
|
}
|
|
@@ -39048,7 +39202,9 @@ class MenuButton extends GNCoreInstance {
|
|
|
39048
39202
|
super(name, selector, options);
|
|
39049
39203
|
this._hidden = {
|
|
39050
39204
|
open: () => {
|
|
39051
|
-
|
|
39205
|
+
if (!this.$options.disabled) {
|
|
39206
|
+
addClass(this.$el, 'is-open');
|
|
39207
|
+
}
|
|
39052
39208
|
},
|
|
39053
39209
|
close: () => {
|
|
39054
39210
|
removeClass(this.$el, 'is-open');
|
|
@@ -39060,6 +39216,62 @@ class MenuButton extends GNCoreInstance {
|
|
|
39060
39216
|
changeText: (buttonText) => {
|
|
39061
39217
|
this.$options.textSets.buttonText = buttonText;
|
|
39062
39218
|
html(find('.menuButton-text', this.$el), buttonText);
|
|
39219
|
+
},
|
|
39220
|
+
disable: () => {
|
|
39221
|
+
this.$options.disabled = true;
|
|
39222
|
+
const buttonEl = find('button', this.$el);
|
|
39223
|
+
if (buttonEl) {
|
|
39224
|
+
attr(buttonEl, 'disabled', true);
|
|
39225
|
+
}
|
|
39226
|
+
addClass(this.$el, 'is-disabled');
|
|
39227
|
+
this._hidden.close();
|
|
39228
|
+
},
|
|
39229
|
+
enable: () => {
|
|
39230
|
+
this.$options.disabled = false;
|
|
39231
|
+
const buttonEl = find('button', this.$el);
|
|
39232
|
+
if (buttonEl) {
|
|
39233
|
+
removeAttr(buttonEl, 'disabled');
|
|
39234
|
+
}
|
|
39235
|
+
removeClass(this.$el, 'is-disabled');
|
|
39236
|
+
},
|
|
39237
|
+
renderMenus: (menus, depth = 0, parentPath = '') => {
|
|
39238
|
+
return (createElement$1("ul", { className: depth > 0 ? 'menuButton-submenu' : '' }, menus.map((menu, index) => {
|
|
39239
|
+
const hasChild = menu.child && isArray$1(menu.child) && menu.child.length > 0;
|
|
39240
|
+
const hasHtml = !!menu.html;
|
|
39241
|
+
// html이 있으면 innerHTML이 모든 자식 요소를 덮어쓰므로 서브메뉴를 렌더링하지 않음
|
|
39242
|
+
const canRenderChild = hasChild && depth < 2 && !hasHtml; // 최대 2단계까지만 허용
|
|
39243
|
+
const isDisabled = menu.disabled === true;
|
|
39244
|
+
const isActived = menu.actived === true;
|
|
39245
|
+
// 부모 경로를 포함한 고유한 ID 생성
|
|
39246
|
+
const currentPath = parentPath ? `${parentPath}-${index}` : `${index}`;
|
|
39247
|
+
const uniqueId = `${this._uid}-${currentPath}`;
|
|
39248
|
+
return (createElement$1("li", { id: uniqueId, className: 'menuButton-menu' +
|
|
39249
|
+
(this.$options.align ? ' has-text-' + this.$options.align : '') +
|
|
39250
|
+
(canRenderChild ? ' has-submenu' : '') +
|
|
39251
|
+
(depth > 0 ? ' is-submenu-item' : '') +
|
|
39252
|
+
(isDisabled ? ' is-disabled' : '') +
|
|
39253
|
+
(isActived ? ' is-actived' : ''), "on-click": (e) => {
|
|
39254
|
+
// disabled 상태이거나 자식 메뉴가 있는 경우 클릭 이벤트 처리하지 않음
|
|
39255
|
+
if (isDisabled) {
|
|
39256
|
+
e.stopPropagation();
|
|
39257
|
+
e.preventDefault();
|
|
39258
|
+
return;
|
|
39259
|
+
}
|
|
39260
|
+
// 자식 메뉴가 없는 경우에만 select 이벤트 발생
|
|
39261
|
+
if (!canRenderChild) {
|
|
39262
|
+
e.stopPropagation();
|
|
39263
|
+
this._hidden.select.call(this, menu, e);
|
|
39264
|
+
}
|
|
39265
|
+
}, innerHTML: hasHtml ? menu.html : '' },
|
|
39266
|
+
hasHtml ? ('') : (createElement$1("span", { className: "menuButton-menu-content" },
|
|
39267
|
+
createElement$1("span", { className: "menuButton-menu-text" }, menu.text),
|
|
39268
|
+
canRenderChild && (createElement$1("span", { className: "menuButton-menu-arrow" },
|
|
39269
|
+
createElement$1("i", { className: "fas fa-caret-right" }))))),
|
|
39270
|
+
canRenderChild && this._hidden.renderMenus.call(this, menu.child, depth + 1, currentPath)));
|
|
39271
|
+
})));
|
|
39272
|
+
},
|
|
39273
|
+
renderSub: (data) => {
|
|
39274
|
+
return createElement$1("div", null, isArray$1(data) && data.length && isArray$1(data[0]) ? data.map((menus) => this._hidden.renderMenus.call(this, menus)) : this._hidden.renderMenus.call(this, data));
|
|
39063
39275
|
}
|
|
39064
39276
|
};
|
|
39065
39277
|
this.config = {
|
|
@@ -39079,6 +39291,19 @@ class MenuButton extends GNCoreInstance {
|
|
|
39079
39291
|
},
|
|
39080
39292
|
buttonText(text) {
|
|
39081
39293
|
this._hidden.changeText(text);
|
|
39294
|
+
},
|
|
39295
|
+
reRender(data) {
|
|
39296
|
+
this.$options.data = data;
|
|
39297
|
+
const menuMenusEl = find('.menuButton-menus > div', this.$el);
|
|
39298
|
+
if (menuMenusEl && this.$template) {
|
|
39299
|
+
this.$template.reRender(menuMenusEl, this._hidden.renderSub.call(this, data));
|
|
39300
|
+
}
|
|
39301
|
+
},
|
|
39302
|
+
disabled() {
|
|
39303
|
+
this._hidden.disable();
|
|
39304
|
+
},
|
|
39305
|
+
enabled() {
|
|
39306
|
+
this._hidden.enable();
|
|
39082
39307
|
}
|
|
39083
39308
|
};
|
|
39084
39309
|
this.$selector = this.$selector;
|
|
@@ -39089,23 +39314,19 @@ class MenuButton extends GNCoreInstance {
|
|
|
39089
39314
|
if (config.width) {
|
|
39090
39315
|
styles.width = getUnit('width', config.width);
|
|
39091
39316
|
}
|
|
39092
|
-
|
|
39093
|
-
|
|
39094
|
-
|
|
39095
|
-
|
|
39096
|
-
|
|
39097
|
-
|
|
39098
|
-
return createElement$1("div", null, isArray$1(data) && data.length && isArray$1(data[0]) ? data.map((menus) => renderMenus(menus)) : renderMenus(data));
|
|
39099
|
-
};
|
|
39100
|
-
return (createElement$1("div", { id: this._uid, className: 'gn-menuButton' + (config.color ? ' is-' + config.color : '') + (config.style ? ' is-' + config.style : '') + (config.size ? ' is-' + config.size : ''), style: styles },
|
|
39101
|
-
createElement$1("button", { type: "button", className: config.align ? 'has-text-' + config.align : '', "on-click": this._hidden.open },
|
|
39317
|
+
return (createElement$1("div", { id: this._uid, className: 'gn-menuButton' +
|
|
39318
|
+
(config.color ? ' is-' + config.color : '') +
|
|
39319
|
+
(config.style ? ' is-' + config.style : '') +
|
|
39320
|
+
(config.size ? ' is-' + config.size : '') +
|
|
39321
|
+
(config.disabled ? ' is-disabled' : ''), style: styles },
|
|
39322
|
+
createElement$1("button", { type: "button", className: config.align ? 'has-text-' + config.align : '', disabled: config.disabled, "on-click": this._hidden.open },
|
|
39102
39323
|
config.icon && (createElement$1("span", { className: 'gn-icon is-' + (config.size === 'large' ? 'medium' : config.size === 'medium' ? 'normal' : 'small') },
|
|
39103
39324
|
createElement$1("i", { className: 'fas fa-' + config.icon }),
|
|
39104
39325
|
' ')),
|
|
39105
39326
|
createElement$1("span", { className: "gn-icon is-small menuButton-icon" },
|
|
39106
39327
|
createElement$1("i", { className: "fas fa-caret-down" })),
|
|
39107
39328
|
createElement$1("span", { className: "menuButton-text" }, config.textSets.buttonText)),
|
|
39108
|
-
createElement$1("div", { className: "menuButton-menus" }, renderSub(config.data))));
|
|
39329
|
+
createElement$1("div", { className: "menuButton-menus" }, this._hidden.renderSub.call(this, config.data))));
|
|
39109
39330
|
}
|
|
39110
39331
|
completed() {
|
|
39111
39332
|
// 해당 컴포넌트 외 클릭 시 menu panel 숨김
|
|
@@ -39316,6 +39537,7 @@ class MultiTextArea extends GNCoreInstance {
|
|
|
39316
39537
|
}
|
|
39317
39538
|
}
|
|
39318
39539
|
|
|
39540
|
+
library$1.add(icons$1, icons);
|
|
39319
39541
|
class Picklist extends GNCoreInstance {
|
|
39320
39542
|
constructor(name, selector, options = {}) {
|
|
39321
39543
|
super(name, selector, options);
|
|
@@ -39457,17 +39679,26 @@ class Picklist extends GNCoreInstance {
|
|
|
39457
39679
|
},
|
|
39458
39680
|
renderSub: (item) => {
|
|
39459
39681
|
const items = this.$options.data[item] || [];
|
|
39460
|
-
return (createElement$1("ul", null, items.map((option, index) =>
|
|
39461
|
-
|
|
39462
|
-
|
|
39463
|
-
|
|
39464
|
-
|
|
39465
|
-
|
|
39466
|
-
|
|
39682
|
+
return (createElement$1("ul", null, items.map((option, index) => {
|
|
39683
|
+
var _a;
|
|
39684
|
+
return (createElement$1("li", { id: this._uid + '_opt_' + index, className: 'dropdown-item' + (option.selected ? ' is-active' : ''), "data-value": option.value, "on-click": !option.text ? null : this._hidden.toggle.bind(this), "on-dblclick": !option.text
|
|
39685
|
+
? null
|
|
39686
|
+
: this._hidden.move.bind(this, item === 'source' ? 'add' : 'remove', [
|
|
39687
|
+
{
|
|
39688
|
+
value: option.value,
|
|
39689
|
+
text: option.text,
|
|
39690
|
+
html: (_a = option.html) !== null && _a !== void 0 ? _a : null
|
|
39691
|
+
}
|
|
39692
|
+
]) },
|
|
39693
|
+
createElement$1("span", { className: "dropdown-text", innerHTML: option.html ? option.html : '' }, option.html ? ('') : option.icon ? (createElement$1("span", null,
|
|
39694
|
+
createElement$1("span", { className: 'gn-icon' + (this.$options.size ? ' is-' + this.$options.size : '') },
|
|
39695
|
+
createElement$1("i", { className: (this.isBrandIcon(option.icon) ? 'fab' : 'fa') + ` fa-${option.icon}` })),
|
|
39696
|
+
escapeEntity(option.text))) : (escapeEntity(option.text)))));
|
|
39697
|
+
})));
|
|
39467
39698
|
},
|
|
39468
39699
|
getSelection: (target) => {
|
|
39469
39700
|
return findAll('.is-active', this.$options.delegates[target]).map((select) => {
|
|
39470
|
-
return
|
|
39701
|
+
return this.$options.data[target].find((option) => option.value === attr(select, 'data-value'));
|
|
39471
39702
|
});
|
|
39472
39703
|
},
|
|
39473
39704
|
disable: () => {
|
|
@@ -39627,6 +39858,11 @@ class Picklist extends GNCoreInstance {
|
|
|
39627
39858
|
style(find('.picklist-target .dropdown-items', this.$el), 'height', getUnit('height', getNumber(this.$options.height) - getNumber(style(find('.picklist-target .picklist-caption', this.$el), 'height'))));
|
|
39628
39859
|
}
|
|
39629
39860
|
}
|
|
39861
|
+
isBrandIcon(iconName) {
|
|
39862
|
+
const iconLookup = { prefix: 'fab', iconName: iconName };
|
|
39863
|
+
const iconDefinition = findIconDefinition$1(iconLookup);
|
|
39864
|
+
return iconDefinition !== undefined;
|
|
39865
|
+
}
|
|
39630
39866
|
}
|
|
39631
39867
|
|
|
39632
39868
|
class Progressbar extends GNCoreInstance {
|
|
@@ -39785,6 +40021,409 @@ class SelectButton extends GNCoreInstance {
|
|
|
39785
40021
|
}
|
|
39786
40022
|
}
|
|
39787
40023
|
|
|
40024
|
+
const CLASS_DRAGGING = 'is-dragging';
|
|
40025
|
+
const CLASS_GROUP_DRAGGING = 'is-group-dragging';
|
|
40026
|
+
const CLASS_DRAG_OVER_TOP = 'is-drag-over-top';
|
|
40027
|
+
const CLASS_DRAG_OVER_BOTTOM = 'is-drag-over-bottom';
|
|
40028
|
+
const DEFAULT_NO_DATA = 'No records available.';
|
|
40029
|
+
const DRAG_STATE_CLASSES = [CLASS_DRAGGING, CLASS_GROUP_DRAGGING, CLASS_DRAG_OVER_TOP, CLASS_DRAG_OVER_BOTTOM];
|
|
40030
|
+
class SortableList extends GNCoreInstance {
|
|
40031
|
+
constructor(name, selector, options = {}) {
|
|
40032
|
+
super(name, selector, options);
|
|
40033
|
+
this._dragging = null;
|
|
40034
|
+
this._selection = new Set();
|
|
40035
|
+
this.DRAG_IMAGE_OFFSET_X = 0;
|
|
40036
|
+
this.DRAG_IMAGE_OFFSET_Y = 0;
|
|
40037
|
+
this.DRAG_OVER_THRESHOLD_RATIO = 0.5;
|
|
40038
|
+
this._hidden = {
|
|
40039
|
+
toggle: (e) => {
|
|
40040
|
+
if (this.$options.disabled) {
|
|
40041
|
+
return;
|
|
40042
|
+
}
|
|
40043
|
+
const value = attr(e.currentTarget, 'data-value');
|
|
40044
|
+
const hasItem = this.$options.data.some((option) => option.value === value);
|
|
40045
|
+
if (!value || !hasItem) {
|
|
40046
|
+
return;
|
|
40047
|
+
}
|
|
40048
|
+
if (this._selection.has(value)) {
|
|
40049
|
+
this._selection.delete(value);
|
|
40050
|
+
removeClass(e.currentTarget, 'is-active');
|
|
40051
|
+
}
|
|
40052
|
+
else {
|
|
40053
|
+
this._selection.add(value);
|
|
40054
|
+
addClass(e.currentTarget, 'is-active');
|
|
40055
|
+
}
|
|
40056
|
+
},
|
|
40057
|
+
sort: (dir) => {
|
|
40058
|
+
const items = this.$options.data || [];
|
|
40059
|
+
const selected = this._hidden.getSelection();
|
|
40060
|
+
if (!selected.length || selected.length === items.length) {
|
|
40061
|
+
return;
|
|
40062
|
+
}
|
|
40063
|
+
const selectedValues = new Set(selected.map((item) => item.value));
|
|
40064
|
+
// dir: up/down → 이동, up-all/down-all → 맨 위/맨 아래로 보내기
|
|
40065
|
+
if (dir.indexOf('all') > -1) {
|
|
40066
|
+
this.$options.data = items.slice().sort((a, b) => {
|
|
40067
|
+
const _sort = dir === 'up-all' ? -1 : 1;
|
|
40068
|
+
const aSel = selectedValues.has(a.value);
|
|
40069
|
+
const bSel = selectedValues.has(b.value);
|
|
40070
|
+
if (aSel && bSel) {
|
|
40071
|
+
return 0;
|
|
40072
|
+
}
|
|
40073
|
+
else if (aSel) {
|
|
40074
|
+
return _sort;
|
|
40075
|
+
}
|
|
40076
|
+
else if (bSel) {
|
|
40077
|
+
return _sort * -1;
|
|
40078
|
+
}
|
|
40079
|
+
return 0;
|
|
40080
|
+
});
|
|
40081
|
+
}
|
|
40082
|
+
else {
|
|
40083
|
+
if (dir === 'up') {
|
|
40084
|
+
const reordered = items.slice();
|
|
40085
|
+
// 한 번에 한 칸씩만 올려 상대 순서를 유지한다
|
|
40086
|
+
for (let i = 1; i < reordered.length; i++) {
|
|
40087
|
+
if (!selectedValues.has(reordered[i].value) || selectedValues.has(reordered[i - 1].value)) {
|
|
40088
|
+
continue;
|
|
40089
|
+
}
|
|
40090
|
+
const temp = reordered[i - 1];
|
|
40091
|
+
reordered[i - 1] = reordered[i];
|
|
40092
|
+
reordered[i] = temp;
|
|
40093
|
+
}
|
|
40094
|
+
this.$options.data = reordered;
|
|
40095
|
+
}
|
|
40096
|
+
else {
|
|
40097
|
+
let reordered = [];
|
|
40098
|
+
let itemsToMoveDown = [];
|
|
40099
|
+
items.forEach((option) => {
|
|
40100
|
+
// reordered: 최종 순서를 쌓는 버퍼, itemsToMoveDown: 아래로 밀어야 할 선택 항목 임시 저장
|
|
40101
|
+
// 비선택 항목은 흐름대로 push, 선택 항목은 dir에 따라 위/아래로 밀어 넣음
|
|
40102
|
+
if (!selectedValues.has(option.value)) {
|
|
40103
|
+
reordered.push(option);
|
|
40104
|
+
if (itemsToMoveDown.length) {
|
|
40105
|
+
reordered = reordered.concat(itemsToMoveDown);
|
|
40106
|
+
itemsToMoveDown = [];
|
|
40107
|
+
}
|
|
40108
|
+
}
|
|
40109
|
+
else if (dir === 'down') {
|
|
40110
|
+
itemsToMoveDown.push(option);
|
|
40111
|
+
}
|
|
40112
|
+
});
|
|
40113
|
+
if (itemsToMoveDown.length) {
|
|
40114
|
+
reordered = reordered.concat(itemsToMoveDown);
|
|
40115
|
+
itemsToMoveDown = [];
|
|
40116
|
+
}
|
|
40117
|
+
this.$options.data = reordered.slice();
|
|
40118
|
+
}
|
|
40119
|
+
}
|
|
40120
|
+
this._hidden.reRender();
|
|
40121
|
+
this._hidden.updateControls();
|
|
40122
|
+
this.$event(this, 'onChange', this.$options.data);
|
|
40123
|
+
},
|
|
40124
|
+
renderSub: () => {
|
|
40125
|
+
var _a, _b;
|
|
40126
|
+
const items = this.$options.data || [];
|
|
40127
|
+
const hasCols = items.some((item) => isArray$1(item.cols) && item.cols.length);
|
|
40128
|
+
if (!items.length) {
|
|
40129
|
+
return (createElement$1("ul", { className: "sortablelist-rows" },
|
|
40130
|
+
createElement$1("li", { className: "dropdown-item is-empty" }, (_b = (_a = this.$options.textSets) === null || _a === void 0 ? void 0 : _a.noData) !== null && _b !== void 0 ? _b : DEFAULT_NO_DATA)));
|
|
40131
|
+
}
|
|
40132
|
+
return (createElement$1("ul", { className: 'sortablelist-rows' + (hasCols ? ' is-cols' : '') }, items.map((option, index) => {
|
|
40133
|
+
var _a;
|
|
40134
|
+
return (createElement$1("li", { id: this._uid + '_opt_' + index, className: 'dropdown-item' + (this._selection.has(option.value) ? ' is-active' : ''), "data-value": option.value, draggable: this.$options.draggable && !this.$options.disabled ? true : null, "on-click": this._hidden.toggle.bind(this), "on-dragstart": this.$options.draggable ? this._hidden.dragStart.bind(this) : null, "on-dragover": this.$options.draggable ? this._hidden.dragOver.bind(this) : null, "on-dragleave": this.$options.draggable ? this._hidden.dragLeave.bind(this) : null, "on-drop": this.$options.draggable ? this._hidden.drop.bind(this) : null, "on-dragend": this.$options.draggable ? this._hidden.dragEnd.bind(this) : null }, hasCols && isArray$1(option.cols) && option.cols.length ? (createElement$1("div", { className: "sortablelist-cols" }, option.cols.map((col, colIndex) => (createElement$1("span", { className: "sortablelist-col", "data-col": colIndex }, escapeEntity(col)))))) : (createElement$1("span", { className: "dropdown-text" }, escapeEntity((_a = option.text) !== null && _a !== void 0 ? _a : option.value)))));
|
|
40135
|
+
})));
|
|
40136
|
+
},
|
|
40137
|
+
getSelection: () => {
|
|
40138
|
+
return this.$options.data.filter((option) => this._selection.has(option.value));
|
|
40139
|
+
},
|
|
40140
|
+
reRender: () => {
|
|
40141
|
+
const listContainer = find('ul', this.$options.delegates.list);
|
|
40142
|
+
listContainer && this.$template.reRender(listContainer, this._hidden.renderSub());
|
|
40143
|
+
},
|
|
40144
|
+
syncSelection: () => {
|
|
40145
|
+
const values = new Set(this.$options.data.map((item) => item.value));
|
|
40146
|
+
this._selection.forEach(val => {
|
|
40147
|
+
if (!values.has(val)) {
|
|
40148
|
+
this._selection.delete(val);
|
|
40149
|
+
}
|
|
40150
|
+
});
|
|
40151
|
+
},
|
|
40152
|
+
hydrateSelection: (items) => {
|
|
40153
|
+
this._selection.clear();
|
|
40154
|
+
items.forEach((item) => {
|
|
40155
|
+
if (item.selected) {
|
|
40156
|
+
this._selection.add(item.value);
|
|
40157
|
+
}
|
|
40158
|
+
});
|
|
40159
|
+
},
|
|
40160
|
+
validateData: (items) => {
|
|
40161
|
+
if (!isArray$1(items)) {
|
|
40162
|
+
throw new TypeError('Invalid SortableList data: data must be an array');
|
|
40163
|
+
}
|
|
40164
|
+
const seen = new Set();
|
|
40165
|
+
items.forEach((item) => {
|
|
40166
|
+
if (!item || typeof item.value !== 'string') {
|
|
40167
|
+
throw new TypeError('Invalid SortableList data: value must be string');
|
|
40168
|
+
}
|
|
40169
|
+
if (item.value === '') {
|
|
40170
|
+
throw new TypeError('Invalid SortableList data: value cannot be empty');
|
|
40171
|
+
}
|
|
40172
|
+
if (seen.has(item.value)) {
|
|
40173
|
+
throw new TypeError(`Invalid SortableList data: duplicate value '${item.value}'`);
|
|
40174
|
+
}
|
|
40175
|
+
seen.add(item.value);
|
|
40176
|
+
});
|
|
40177
|
+
},
|
|
40178
|
+
updateControls: () => {
|
|
40179
|
+
const hasData = (this.$options.data || []).length > 0;
|
|
40180
|
+
const disableButtons = this.$options.disabled || !hasData;
|
|
40181
|
+
if (disableButtons) {
|
|
40182
|
+
attr(findAll('button', this.$el), 'disabled', true);
|
|
40183
|
+
}
|
|
40184
|
+
else {
|
|
40185
|
+
removeAttr(findAll('button', this.$el), 'disabled');
|
|
40186
|
+
}
|
|
40187
|
+
if (!hasData) {
|
|
40188
|
+
addClass(this.$el, 'is-empty');
|
|
40189
|
+
}
|
|
40190
|
+
else {
|
|
40191
|
+
removeClass(this.$el, 'is-empty');
|
|
40192
|
+
}
|
|
40193
|
+
},
|
|
40194
|
+
clearDragState: () => {
|
|
40195
|
+
var _a;
|
|
40196
|
+
DRAG_STATE_CLASSES.forEach(className => {
|
|
40197
|
+
removeClass(findAll(`.${className}`, this.$el), className);
|
|
40198
|
+
});
|
|
40199
|
+
if ((_a = this._dragging) === null || _a === void 0 ? void 0 : _a.preview) {
|
|
40200
|
+
this._dragging.preview.remove();
|
|
40201
|
+
}
|
|
40202
|
+
this._dragging = null;
|
|
40203
|
+
},
|
|
40204
|
+
dragStart: (e) => {
|
|
40205
|
+
if (this.$options.disabled || !this.$options.draggable) {
|
|
40206
|
+
return;
|
|
40207
|
+
}
|
|
40208
|
+
// 기존 드래그 상태 정리 (이전 드래그가 중단된 경우 대비)
|
|
40209
|
+
this._hidden.clearDragState();
|
|
40210
|
+
const value = attr(e.currentTarget, 'data-value');
|
|
40211
|
+
if (!value) {
|
|
40212
|
+
return;
|
|
40213
|
+
}
|
|
40214
|
+
const selected = this._hidden.getSelection().map((item) => item.value);
|
|
40215
|
+
const isGroup = selected.length > 1 && selected.includes(value);
|
|
40216
|
+
const dragValues = isGroup ? selected : [value];
|
|
40217
|
+
this._dragging = { values: dragValues, isGroup: isGroup, preview: null };
|
|
40218
|
+
if (e.dataTransfer) {
|
|
40219
|
+
e.dataTransfer.setData('text/plain', value);
|
|
40220
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
40221
|
+
if (isGroup) {
|
|
40222
|
+
const preview = document.createElement('div');
|
|
40223
|
+
preview.className = 'sortablelist-drag-preview';
|
|
40224
|
+
preview.setAttribute('data-count', String(dragValues.length));
|
|
40225
|
+
const list = document.createElement('div');
|
|
40226
|
+
list.className = 'sortablelist-drag-preview-list';
|
|
40227
|
+
dragValues.forEach((dragValue) => {
|
|
40228
|
+
const itemEl = find(`[data-value="${CSS.escape(dragValue)}"]`, this.$options.delegates.list);
|
|
40229
|
+
if (!(itemEl instanceof HTMLElement)) {
|
|
40230
|
+
return;
|
|
40231
|
+
}
|
|
40232
|
+
const clone = itemEl.cloneNode(true);
|
|
40233
|
+
removeClass(clone, CLASS_DRAGGING);
|
|
40234
|
+
removeClass(clone, CLASS_GROUP_DRAGGING);
|
|
40235
|
+
removeClass(clone, CLASS_DRAG_OVER_TOP);
|
|
40236
|
+
removeClass(clone, CLASS_DRAG_OVER_BOTTOM);
|
|
40237
|
+
addClass(clone, 'is-ghost');
|
|
40238
|
+
list.appendChild(clone);
|
|
40239
|
+
});
|
|
40240
|
+
preview.appendChild(list);
|
|
40241
|
+
document.body.appendChild(preview);
|
|
40242
|
+
e.dataTransfer.setDragImage(preview, this.DRAG_IMAGE_OFFSET_X, this.DRAG_IMAGE_OFFSET_Y);
|
|
40243
|
+
this._dragging.preview = preview;
|
|
40244
|
+
}
|
|
40245
|
+
}
|
|
40246
|
+
findAll('.dropdown-item', this.$options.delegates.list).forEach((node) => {
|
|
40247
|
+
const itemValue = attr(node, 'data-value');
|
|
40248
|
+
if (dragValues.includes(itemValue)) {
|
|
40249
|
+
addClass(node, CLASS_DRAGGING);
|
|
40250
|
+
if (isGroup) {
|
|
40251
|
+
addClass(node, CLASS_GROUP_DRAGGING);
|
|
40252
|
+
}
|
|
40253
|
+
}
|
|
40254
|
+
});
|
|
40255
|
+
},
|
|
40256
|
+
dragOver: (e) => {
|
|
40257
|
+
if (!this._dragging || this.$options.disabled || !this.$options.draggable) {
|
|
40258
|
+
return;
|
|
40259
|
+
}
|
|
40260
|
+
e.preventDefault();
|
|
40261
|
+
if (!(e.currentTarget instanceof HTMLElement)) {
|
|
40262
|
+
return;
|
|
40263
|
+
}
|
|
40264
|
+
const target = e.currentTarget;
|
|
40265
|
+
const value = attr(target, 'data-value');
|
|
40266
|
+
if (this._dragging.values.includes(value)) {
|
|
40267
|
+
return;
|
|
40268
|
+
}
|
|
40269
|
+
removeClass(target, CLASS_DRAG_OVER_TOP);
|
|
40270
|
+
removeClass(target, CLASS_DRAG_OVER_BOTTOM);
|
|
40271
|
+
const rect = target.getBoundingClientRect();
|
|
40272
|
+
const midpoint = rect.top + rect.height * this.DRAG_OVER_THRESHOLD_RATIO;
|
|
40273
|
+
if (e.clientY > midpoint) {
|
|
40274
|
+
addClass(target, CLASS_DRAG_OVER_BOTTOM);
|
|
40275
|
+
}
|
|
40276
|
+
else {
|
|
40277
|
+
addClass(target, CLASS_DRAG_OVER_TOP);
|
|
40278
|
+
}
|
|
40279
|
+
},
|
|
40280
|
+
dragLeave: (e) => {
|
|
40281
|
+
if (e.currentTarget instanceof HTMLElement) {
|
|
40282
|
+
removeClass(e.currentTarget, 'is-drag-over-top');
|
|
40283
|
+
removeClass(e.currentTarget, 'is-drag-over-bottom');
|
|
40284
|
+
}
|
|
40285
|
+
},
|
|
40286
|
+
drop: (e) => {
|
|
40287
|
+
if (!this._dragging || this.$options.disabled || !this.$options.draggable) {
|
|
40288
|
+
return;
|
|
40289
|
+
}
|
|
40290
|
+
e.preventDefault();
|
|
40291
|
+
if (!(e.currentTarget instanceof HTMLElement)) {
|
|
40292
|
+
return;
|
|
40293
|
+
}
|
|
40294
|
+
const targetEl = e.currentTarget;
|
|
40295
|
+
const targetValue = attr(targetEl, 'data-value');
|
|
40296
|
+
const dragValues = this._dragging.values;
|
|
40297
|
+
if (!targetValue || dragValues.includes(targetValue)) {
|
|
40298
|
+
this._hidden.clearDragState();
|
|
40299
|
+
return;
|
|
40300
|
+
}
|
|
40301
|
+
const items = this.$options.data;
|
|
40302
|
+
const dragItems = items.filter((item) => dragValues.includes(item.value));
|
|
40303
|
+
const remain = items.filter((item) => !dragValues.includes(item.value));
|
|
40304
|
+
const targetIndex = remain.findIndex((item) => item.value === targetValue);
|
|
40305
|
+
const rect = targetEl.getBoundingClientRect();
|
|
40306
|
+
const midpoint = rect.top + rect.height * this.DRAG_OVER_THRESHOLD_RATIO;
|
|
40307
|
+
const insertAfter = e.clientY > midpoint;
|
|
40308
|
+
const insertIndex = targetIndex === -1 ? remain.length : insertAfter ? targetIndex + 1 : targetIndex;
|
|
40309
|
+
remain.splice(insertIndex, 0, ...dragItems);
|
|
40310
|
+
this.$options.data = remain;
|
|
40311
|
+
this._hidden.reRender();
|
|
40312
|
+
this._hidden.updateControls();
|
|
40313
|
+
this.$event(this, 'onChange', this.$options.data);
|
|
40314
|
+
this._hidden.clearDragState();
|
|
40315
|
+
},
|
|
40316
|
+
dragEnd: () => {
|
|
40317
|
+
this._hidden.clearDragState();
|
|
40318
|
+
},
|
|
40319
|
+
setData: (data) => {
|
|
40320
|
+
// 드래그 중일 경우 상태 정리 (DOM 요소가 제거되면 dragend 이벤트가 발생하지 않을 수 있음)
|
|
40321
|
+
this._hidden.clearDragState();
|
|
40322
|
+
this._hidden.validateData(data);
|
|
40323
|
+
this.$options.data = data;
|
|
40324
|
+
this._hidden.hydrateSelection(data);
|
|
40325
|
+
this._hidden.syncSelection();
|
|
40326
|
+
this._hidden.reRender();
|
|
40327
|
+
this._hidden.updateControls();
|
|
40328
|
+
this.$event(this, 'onChange', this.$options.data);
|
|
40329
|
+
},
|
|
40330
|
+
disable: () => {
|
|
40331
|
+
// 드래그 중일 경우 상태 정리
|
|
40332
|
+
this._hidden.clearDragState();
|
|
40333
|
+
this.$options.disabled = true;
|
|
40334
|
+
addClass(this.$el, 'is-disabled');
|
|
40335
|
+
this._hidden.reRender();
|
|
40336
|
+
this._hidden.updateControls();
|
|
40337
|
+
},
|
|
40338
|
+
enable: () => {
|
|
40339
|
+
// 드래그 중일 경우 상태 정리
|
|
40340
|
+
this._hidden.clearDragState();
|
|
40341
|
+
this.$options.disabled = false;
|
|
40342
|
+
removeClass(this.$el, 'is-disabled');
|
|
40343
|
+
this._hidden.reRender();
|
|
40344
|
+
this._hidden.updateControls();
|
|
40345
|
+
}
|
|
40346
|
+
};
|
|
40347
|
+
this.config = {
|
|
40348
|
+
name: this.$selector.name || this._uid,
|
|
40349
|
+
data: [],
|
|
40350
|
+
delegates: {
|
|
40351
|
+
list: '.sortablelist-items'
|
|
40352
|
+
},
|
|
40353
|
+
buttonPosition: 'left',
|
|
40354
|
+
draggable: false,
|
|
40355
|
+
textSets: {
|
|
40356
|
+
noData: DEFAULT_NO_DATA
|
|
40357
|
+
},
|
|
40358
|
+
height: 150
|
|
40359
|
+
};
|
|
40360
|
+
this.events = {
|
|
40361
|
+
onChange: true
|
|
40362
|
+
};
|
|
40363
|
+
this.methods = {
|
|
40364
|
+
getData() {
|
|
40365
|
+
return this.$options.data;
|
|
40366
|
+
},
|
|
40367
|
+
setData(data) {
|
|
40368
|
+
const next = isArray$1(data) ? data : data && 'data' in data ? data.data : null;
|
|
40369
|
+
if (!isArray$1(next)) {
|
|
40370
|
+
throw new TypeError('Invalid SortableList data: data must be an array');
|
|
40371
|
+
}
|
|
40372
|
+
this._hidden.setData(next);
|
|
40373
|
+
},
|
|
40374
|
+
disable() {
|
|
40375
|
+
this._hidden.disable();
|
|
40376
|
+
},
|
|
40377
|
+
enable() {
|
|
40378
|
+
this._hidden.enable();
|
|
40379
|
+
}
|
|
40380
|
+
};
|
|
40381
|
+
this.$selector = this.$selector;
|
|
40382
|
+
this.$init(this, options);
|
|
40383
|
+
}
|
|
40384
|
+
template(config) {
|
|
40385
|
+
const styles = {};
|
|
40386
|
+
if (config.width) {
|
|
40387
|
+
styles.width = getUnit('width', config.width);
|
|
40388
|
+
}
|
|
40389
|
+
const listStyles = {};
|
|
40390
|
+
if (config.height) {
|
|
40391
|
+
const heightValue = getUnit('height', config.height);
|
|
40392
|
+
styles.height = heightValue;
|
|
40393
|
+
listStyles.height = heightValue;
|
|
40394
|
+
listStyles.maxHeight = heightValue;
|
|
40395
|
+
}
|
|
40396
|
+
const controlClass = 'sortablelist-controls gn-control is-small has-arrange is-vertical is-center' + (config.buttonPosition === 'right' ? ' is-right' : '');
|
|
40397
|
+
const buttonDisabled = config.disabled || (config.data || []).length === 0;
|
|
40398
|
+
return (createElement$1("div", { id: this._uid, className: 'gn-sortablelist' + (config.disabled ? ' is-disabled' : ''), style: styles },
|
|
40399
|
+
createElement$1("div", { className: controlClass },
|
|
40400
|
+
createElement$1("button", { type: "button", className: "gn-button is-outline", "on-click": this._hidden.sort.bind(this, 'up-all'), disabled: buttonDisabled },
|
|
40401
|
+
createElement$1("span", { className: "gn-icon" },
|
|
40402
|
+
createElement$1("i", { className: "fa fa-light fa-angle-double-up" }))),
|
|
40403
|
+
createElement$1("button", { type: "button", className: "gn-button is-outline", "on-click": this._hidden.sort.bind(this, 'up'), disabled: buttonDisabled },
|
|
40404
|
+
createElement$1("span", { className: "gn-icon" },
|
|
40405
|
+
createElement$1("i", { className: "fa fa-light fa-angle-up" }))),
|
|
40406
|
+
createElement$1("button", { type: "button", className: "gn-button is-outline", "on-click": this._hidden.sort.bind(this, 'down'), disabled: buttonDisabled },
|
|
40407
|
+
createElement$1("span", { className: "gn-icon" },
|
|
40408
|
+
createElement$1("i", { className: "fa fa-light fa-angle-down" }))),
|
|
40409
|
+
createElement$1("button", { type: "button", className: "gn-button is-outline", "on-click": this._hidden.sort.bind(this, 'down-all'), disabled: buttonDisabled },
|
|
40410
|
+
createElement$1("span", { className: "gn-icon" },
|
|
40411
|
+
createElement$1("i", { className: "fa fa-light fa-angle-double-down" })))),
|
|
40412
|
+
createElement$1("div", { className: "gn-dropdown is-opened sortablelist-items" },
|
|
40413
|
+
createElement$1("div", { className: "dropdown-items", style: listStyles }, this._hidden.renderSub()))));
|
|
40414
|
+
}
|
|
40415
|
+
beforeMount() {
|
|
40416
|
+
this._hidden.validateData(this.$options.data);
|
|
40417
|
+
this._hidden.hydrateSelection(this.$options.data);
|
|
40418
|
+
}
|
|
40419
|
+
completed() {
|
|
40420
|
+
this._hidden.updateControls();
|
|
40421
|
+
}
|
|
40422
|
+
destroyed() {
|
|
40423
|
+
this._hidden.clearDragState();
|
|
40424
|
+
}
|
|
40425
|
+
}
|
|
40426
|
+
|
|
39788
40427
|
class Splitter extends GNCoreInstance {
|
|
39789
40428
|
constructor(name, selector, options = {}) {
|
|
39790
40429
|
super(name, selector, options);
|
|
@@ -40432,6 +41071,7 @@ var gnUIComp = {
|
|
|
40432
41071
|
picklist: Picklist,
|
|
40433
41072
|
progressbar: Progressbar,
|
|
40434
41073
|
selectbutton: SelectButton,
|
|
41074
|
+
sortablelist: SortableList,
|
|
40435
41075
|
splitter: Splitter,
|
|
40436
41076
|
switch: Switch,
|
|
40437
41077
|
syntaxinput: SyntaxInput,
|