gnui 1.2.16 → 1.2.18
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 +772 -111
- package/dist/js/gnui.js +772 -111
- package/dist/js/gnui.min.js +6 -6
- package/dist/styles/default.css +1018 -108
- package/dist/styles/gpi.css +1018 -108
- package/dist/styles/green24.css +1229 -289
- package/dist/styles/insights.css +1018 -108
- package/dist/styles/nac.css +1019 -109
- package/dist/styles/ztnac.css +1205 -265
- package/package.json +2 -2
- package/styleguide/assets/components.js +216 -9
- package/styleguide/assets/js/gnui.js +772 -111
- package/styleguide/assets/js/gnui.min.js +6 -6
- package/styleguide/assets/styles/default.css +1018 -108
- package/styleguide/assets/styles/gpi.css +1018 -108
- package/styleguide/assets/styles/green24.css +1229 -289
- package/styleguide/assets/styles/insights.css +1018 -108
- package/styleguide/assets/styles/nac.css +1019 -109
- package/styleguide/assets/styles/ztnac.css +1205 -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.js
CHANGED
|
@@ -14118,15 +14118,15 @@
|
|
|
14118
14118
|
if (!obj || !pathString) {
|
|
14119
14119
|
return "";
|
|
14120
14120
|
}
|
|
14121
|
-
|
|
14122
|
-
|
|
14123
|
-
|
|
14124
|
-
|
|
14125
|
-
|
|
14126
|
-
|
|
14127
|
-
|
|
14128
|
-
return "";
|
|
14121
|
+
const keys = isString(pathString) ? pathString.split(".") : pathString;
|
|
14122
|
+
let current = obj;
|
|
14123
|
+
for (const key of keys) {
|
|
14124
|
+
if (current === void 0 || current === null) {
|
|
14125
|
+
return "";
|
|
14126
|
+
}
|
|
14127
|
+
current = current[key];
|
|
14129
14128
|
}
|
|
14129
|
+
return current !== void 0 ? current : "";
|
|
14130
14130
|
}
|
|
14131
14131
|
function findProperty(obj, predicate) {
|
|
14132
14132
|
let result = [];
|
|
@@ -14265,17 +14265,18 @@
|
|
|
14265
14265
|
return dmustach.test(result) ? interpolateURL(result, source) : result;
|
|
14266
14266
|
}
|
|
14267
14267
|
function interpolateCop(textCondition, data2, parent2, $2) {
|
|
14268
|
-
const onlymustach = /^\{{2}[
|
|
14268
|
+
const onlymustach = /^\{{2}[\w.$\[\]]+\}{2}$/;
|
|
14269
14269
|
if (onlymustach.test(textCondition)) {
|
|
14270
14270
|
const path = textCondition.replace("{{", "").replace("}}", "");
|
|
14271
14271
|
return findValue({ data: data2, parent: parent2, $: $2 }, path);
|
|
14272
14272
|
}
|
|
14273
14273
|
const dmustach = new RegExp(/\{{([^{}]*)}}/gm);
|
|
14274
|
+
const context = { data: data2, parent: parent2, $: $2 };
|
|
14274
14275
|
const result = textCondition.replace(dmustach, (match) => {
|
|
14275
14276
|
const conditionalOp = match.replace(/\{{|\}}/gm, "");
|
|
14276
|
-
return new Function("
|
|
14277
|
+
return new Function("ctx", "const {data, parent, $} = ctx; return " + conditionalOp)(context);
|
|
14277
14278
|
});
|
|
14278
|
-
return dmustach.test(result) ?
|
|
14279
|
+
return dmustach.test(result) ? interpolateCop(result, context.data, context.parent, context.$) : result;
|
|
14279
14280
|
}
|
|
14280
14281
|
function parseBundle(text2, locale) {
|
|
14281
14282
|
let _value = text2;
|
|
@@ -14709,7 +14710,10 @@
|
|
|
14709
14710
|
});
|
|
14710
14711
|
}
|
|
14711
14712
|
function getArgs(args) {
|
|
14712
|
-
return args.reduce(
|
|
14713
|
+
return args.reduce(
|
|
14714
|
+
(args2, arg) => args2.concat.call(args2, isString(arg) && includes(arg, " ") ? arg.trim().split(" ") : arg),
|
|
14715
|
+
[]
|
|
14716
|
+
);
|
|
14713
14717
|
}
|
|
14714
14718
|
var supports = {
|
|
14715
14719
|
get Multiple() {
|
|
@@ -14735,7 +14739,7 @@
|
|
|
14735
14739
|
s = s / 100;
|
|
14736
14740
|
l = l / 100;
|
|
14737
14741
|
const c = (1 - Math.abs(2 * l - 1)) * s, x = c * (1 - Math.abs(h / 60 % 2 - 1)), m = l - c / 2;
|
|
14738
|
-
let r, g, b;
|
|
14742
|
+
let r = 0, g = 0, b = 0;
|
|
14739
14743
|
switch (true) {
|
|
14740
14744
|
case (h > -1 && h < 60):
|
|
14741
14745
|
r = c;
|
|
@@ -15014,7 +15018,14 @@
|
|
|
15014
15018
|
function dateData(locale) {
|
|
15015
15019
|
return ["S", "M", "T", "W", "T", "F", "S"];
|
|
15016
15020
|
}
|
|
15017
|
-
function objToDate({
|
|
15021
|
+
function objToDate({
|
|
15022
|
+
year,
|
|
15023
|
+
month,
|
|
15024
|
+
day,
|
|
15025
|
+
hour,
|
|
15026
|
+
minute,
|
|
15027
|
+
second
|
|
15028
|
+
}) {
|
|
15018
15029
|
if (hour === void 0) {
|
|
15019
15030
|
hour = "00";
|
|
15020
15031
|
}
|
|
@@ -15243,7 +15254,11 @@
|
|
|
15243
15254
|
["left", "top"].forEach((prop) => {
|
|
15244
15255
|
if (prop in coordinates) {
|
|
15245
15256
|
const value = css$1(element, prop);
|
|
15246
|
-
css$1(
|
|
15257
|
+
css$1(
|
|
15258
|
+
element,
|
|
15259
|
+
prop,
|
|
15260
|
+
coordinates[prop] - (currentOffset == null ? void 0 : currentOffset[prop]) + toFloat(pos === "absolute" && value === "auto" ? position(element)[prop] : value)
|
|
15261
|
+
);
|
|
15247
15262
|
}
|
|
15248
15263
|
});
|
|
15249
15264
|
}
|
|
@@ -15366,7 +15381,10 @@
|
|
|
15366
15381
|
}
|
|
15367
15382
|
function after(ref, element) {
|
|
15368
15383
|
ref = $(ref);
|
|
15369
|
-
return insertNodes(
|
|
15384
|
+
return insertNodes(
|
|
15385
|
+
element,
|
|
15386
|
+
(element2) => ref.nextSibling ? before(ref.nextSibling, element2) : append(ref.parentNode, element2)
|
|
15387
|
+
);
|
|
15370
15388
|
}
|
|
15371
15389
|
function insertNodes(element, fn) {
|
|
15372
15390
|
element = isString(element) ? fragment(element) : element;
|
|
@@ -15390,13 +15408,21 @@
|
|
|
15390
15408
|
listener = delegate(targets, selector, listener);
|
|
15391
15409
|
}
|
|
15392
15410
|
useCapture = useCaptureFilter(useCapture);
|
|
15393
|
-
type.split(" ").forEach(
|
|
15411
|
+
type.split(" ").forEach(
|
|
15412
|
+
(type2) => targets.forEach(
|
|
15413
|
+
(target) => target.addEventListener(type2, listener, useCapture)
|
|
15414
|
+
)
|
|
15415
|
+
);
|
|
15394
15416
|
return () => off(targets, type, listener, useCapture);
|
|
15395
15417
|
}
|
|
15396
15418
|
function off(targets, type, listener, useCapture = false) {
|
|
15397
15419
|
useCapture = useCaptureFilter(useCapture);
|
|
15398
15420
|
targets = toEventTargets(targets);
|
|
15399
|
-
type.split(" ").forEach(
|
|
15421
|
+
type.split(" ").forEach(
|
|
15422
|
+
(type2) => targets.forEach(
|
|
15423
|
+
(target) => target.removeEventListener(type2, listener, useCapture)
|
|
15424
|
+
)
|
|
15425
|
+
);
|
|
15400
15426
|
}
|
|
15401
15427
|
function once(...args) {
|
|
15402
15428
|
const [element, type, selector, listener, useCapture, condition] = getArgs2(args);
|
|
@@ -15416,7 +15442,10 @@
|
|
|
15416
15442
|
return off2;
|
|
15417
15443
|
}
|
|
15418
15444
|
function trigger(targets, event, detail2) {
|
|
15419
|
-
return toEventTargets(targets).reduce(
|
|
15445
|
+
return toEventTargets(targets).reduce(
|
|
15446
|
+
(notCanceled, target) => notCanceled && target.dispatchEvent(createEvent(event, true, true, detail2)),
|
|
15447
|
+
true
|
|
15448
|
+
);
|
|
15420
15449
|
}
|
|
15421
15450
|
function createEvent(e, bubbles = true, cancelable = false, detail2) {
|
|
15422
15451
|
if (isString(e)) {
|
|
@@ -16901,7 +16930,10 @@
|
|
|
16901
16930
|
// 이벤트 삭제
|
|
16902
16931
|
delete this._eventMap[uid];
|
|
16903
16932
|
}
|
|
16904
|
-
|
|
16933
|
+
/**
|
|
16934
|
+
* lifeCycle 핸들러 실행
|
|
16935
|
+
*/
|
|
16936
|
+
cyclepatch(uid, name, params) {
|
|
16905
16937
|
const _events = this._getEvent(uid, name);
|
|
16906
16938
|
if (_events.length) {
|
|
16907
16939
|
_events.forEach((_event) => {
|
|
@@ -16910,6 +16942,28 @@
|
|
|
16910
16942
|
});
|
|
16911
16943
|
}
|
|
16912
16944
|
}
|
|
16945
|
+
/**
|
|
16946
|
+
* 등록된 이벤트 핸들러 실행
|
|
16947
|
+
*
|
|
16948
|
+
* - sync/async 핸들러를 모두 지원한다.
|
|
16949
|
+
* - 모든 핸들러를 순차 실행한 뒤, 하나라도 `false` 를 반환한 경우 `true`(cancelled)를 반환한다.
|
|
16950
|
+
* (첫 false 에서 중단하지 않고, 나머지 핸들러도 계속 실행한다)
|
|
16951
|
+
*/
|
|
16952
|
+
async dispatch(uid, name, params) {
|
|
16953
|
+
const _events = this._getEvent(uid, name);
|
|
16954
|
+
let cancelled = false;
|
|
16955
|
+
if (_events.length) {
|
|
16956
|
+
for (const _event of _events) {
|
|
16957
|
+
const _target = _event.target || this;
|
|
16958
|
+
// sync/async 둘 다 지원: Promise.resolve 로 감싸서 await
|
|
16959
|
+
const result = await Promise.resolve(params ? _event.handler.call(_target, ...params) : _event.handler.call(_target));
|
|
16960
|
+
if (result === false) {
|
|
16961
|
+
cancelled = true;
|
|
16962
|
+
}
|
|
16963
|
+
}
|
|
16964
|
+
}
|
|
16965
|
+
return cancelled;
|
|
16966
|
+
}
|
|
16913
16967
|
_getEvent(uid, name) {
|
|
16914
16968
|
// parameters에 해당하는 이벤트 반환
|
|
16915
16969
|
return this._eventMap[uid]
|
|
@@ -16994,7 +17048,7 @@
|
|
|
16994
17048
|
});
|
|
16995
17049
|
return _findComponent;
|
|
16996
17050
|
}
|
|
16997
|
-
// 등록된 컴포넌트 제거
|
|
17051
|
+
// 등록된 컴포넌트 제거 (selector 기반)
|
|
16998
17052
|
_removeComponent(selector) {
|
|
16999
17053
|
if (!selector) {
|
|
17000
17054
|
return;
|
|
@@ -17003,10 +17057,30 @@
|
|
|
17003
17057
|
Object.values(this._componentMap).forEach(n => {
|
|
17004
17058
|
// 동일한 selector 인지 비교해서 동일한 component의 selector이면 제거 처리
|
|
17005
17059
|
if (isEquals(n.selector, _selector)) {
|
|
17006
|
-
|
|
17060
|
+
// componentMap에서 완전히 제거
|
|
17061
|
+
delete this._componentMap[n.uid];
|
|
17062
|
+
// 컴포넌트 내부 참조도 제거 (메모리 누수 방지)
|
|
17063
|
+
if (n.component) {
|
|
17064
|
+
n.component = null;
|
|
17065
|
+
}
|
|
17066
|
+
n.selector = null;
|
|
17007
17067
|
}
|
|
17008
17068
|
});
|
|
17009
17069
|
}
|
|
17070
|
+
// 등록된 컴포넌트 제거 (uid 기반 - 더 효율적)
|
|
17071
|
+
_removeComponentByUid(uid) {
|
|
17072
|
+
if (!uid || !this._componentMap[uid]) {
|
|
17073
|
+
return;
|
|
17074
|
+
}
|
|
17075
|
+
// 컴포넌트 내부 참조 제거 (메모리 누수 방지)
|
|
17076
|
+
const componentInfo = this._componentMap[uid];
|
|
17077
|
+
if (componentInfo.component) {
|
|
17078
|
+
componentInfo.component = null;
|
|
17079
|
+
}
|
|
17080
|
+
componentInfo.selector = null;
|
|
17081
|
+
// componentMap에서 완전히 제거
|
|
17082
|
+
delete this._componentMap[uid];
|
|
17083
|
+
}
|
|
17010
17084
|
// 컴포넌트 life cycle에 따른 eventManager dispatch
|
|
17011
17085
|
_detectedCycle(uid, name) {
|
|
17012
17086
|
// component 마지막 status 업데이트
|
|
@@ -17016,7 +17090,7 @@
|
|
|
17016
17090
|
// event manager를 이용해 해당 uid 이벤트 dispatch
|
|
17017
17091
|
const eventManager = GNCoreEventManager.getInstance();
|
|
17018
17092
|
// 호출 후
|
|
17019
|
-
eventManager.
|
|
17093
|
+
eventManager.cyclepatch(uid, name, '');
|
|
17020
17094
|
// 이벤트 해제 - life cycle 은 컴포넌트 별로 한번씩만 존재하므로..
|
|
17021
17095
|
eventManager.remove(uid, name);
|
|
17022
17096
|
}
|
|
@@ -17030,6 +17104,7 @@
|
|
|
17030
17104
|
function _removedNode(removed) {
|
|
17031
17105
|
Array.prototype.forEach.call(removed, (rm) => {
|
|
17032
17106
|
// 삭제노드 연관 컴포넌트 (ex. tooltip) 삭제
|
|
17107
|
+
var _a;
|
|
17033
17108
|
const dependents = findAll('[data-gnui]', rm);
|
|
17034
17109
|
each(dependents, (dependent) => {
|
|
17035
17110
|
if (isElement$2(dependent)) {
|
|
@@ -17043,7 +17118,7 @@
|
|
|
17043
17118
|
remove($('#' + attr(rm, 'data-gnui')));
|
|
17044
17119
|
}
|
|
17045
17120
|
const findComponent = closerThis._getComponent($(rm));
|
|
17046
|
-
if (findComponent && findComponent._uid && !findComponent.$el.parentNode && findComponent.$name !== 'modal') {
|
|
17121
|
+
if (findComponent && findComponent._uid && !((_a = findComponent.$el) === null || _a === void 0 ? void 0 : _a.parentNode) && findComponent.$name !== 'modal') {
|
|
17047
17122
|
// state manager 에서 component 삭제
|
|
17048
17123
|
closerThis._removeComponent(rm);
|
|
17049
17124
|
// event manager 에서 unbind
|
|
@@ -17242,25 +17317,48 @@
|
|
|
17242
17317
|
}
|
|
17243
17318
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
17244
17319
|
$update(element = this.$el, e) { }
|
|
17245
|
-
|
|
17320
|
+
/**
|
|
17321
|
+
* 컴포넌트 이벤트 디스패치 헬퍼
|
|
17322
|
+
*
|
|
17323
|
+
* - sync/async 핸들러 모두 지원한다.
|
|
17324
|
+
* - 하나 이상의 핸들러에서 `false`를 반환하면 `true`(cancelled) 를 반환한다.
|
|
17325
|
+
* - 단순 알림용(fire-and-forget) 이벤트는 반환값/await 없이 호출해도 된다.
|
|
17326
|
+
*/
|
|
17327
|
+
async $event(component, name, ...params) {
|
|
17246
17328
|
const eventManager = GNCoreEventManager.getInstance();
|
|
17247
|
-
eventManager.dispatch(component._uid, name, params);
|
|
17329
|
+
return eventManager.dispatch(component._uid, name, params);
|
|
17248
17330
|
}
|
|
17249
17331
|
$destroy(component = this, removeEl = true) {
|
|
17332
|
+
var _a;
|
|
17250
17333
|
const stateManager = GNUIState.getInstance();
|
|
17251
17334
|
// state manager 를 통해 destroy 상태 dispatch
|
|
17252
17335
|
stateManager._detectedCycle(component._uid, 'destroy');
|
|
17253
|
-
// remove Component in state manager
|
|
17254
|
-
stateManager._removeComponent(component.$selector);
|
|
17255
17336
|
// remove DOM (by removeEl)
|
|
17256
17337
|
if (removeEl) {
|
|
17257
17338
|
style(component.$el, 'display', 'none');
|
|
17258
17339
|
remove(component.$el);
|
|
17259
17340
|
}
|
|
17341
|
+
if (((_a = component.$options) === null || _a === void 0 ? void 0 : _a._destroy) && isFunction(component.$options._destroy)) {
|
|
17342
|
+
component.$options._destroy();
|
|
17343
|
+
}
|
|
17260
17344
|
// state manager 를 통해 destroy 상태 dispatch
|
|
17261
17345
|
stateManager._detectedCycle(component._uid, 'destroyed');
|
|
17262
|
-
// event manager 에서 등록
|
|
17346
|
+
// event manager 에서 등록 해제
|
|
17263
17347
|
GNCoreEventManager.getInstance().removeAll(component._uid);
|
|
17348
|
+
// state manager에서 component 제거 (uid 기반으로 효율적 제거)
|
|
17349
|
+
stateManager._removeComponentByUid(component._uid);
|
|
17350
|
+
// 메모리 누수 방지: component의 모든 hasOwnProperty 제거
|
|
17351
|
+
// config, events, methods, _hidden 등 동적으로 추가된 속성 포함
|
|
17352
|
+
Object.keys(component).forEach((key) => {
|
|
17353
|
+
try {
|
|
17354
|
+
component[key] = null;
|
|
17355
|
+
delete component[key];
|
|
17356
|
+
}
|
|
17357
|
+
catch (e) {
|
|
17358
|
+
// readonly 속성 등 삭제 불가능한 경우 무시
|
|
17359
|
+
}
|
|
17360
|
+
});
|
|
17361
|
+
component = null;
|
|
17264
17362
|
}
|
|
17265
17363
|
}
|
|
17266
17364
|
|
|
@@ -33461,8 +33559,19 @@
|
|
|
33461
33559
|
});
|
|
33462
33560
|
if (this.$options.value) {
|
|
33463
33561
|
if (this.$options.multiple) {
|
|
33464
|
-
|
|
33465
|
-
|
|
33562
|
+
// multiple 모드에서 다양한 타입의 value를 문자열 배열로 변환
|
|
33563
|
+
// 지원 타입: 문자열(쉼표 구분), 객체 배열, 단일 객체, 문자열 배열
|
|
33564
|
+
const values = typeof this.$options.value === 'string'
|
|
33565
|
+
? this.$options.value.split(',') // 케이스 1: 'item1,item2,item3'
|
|
33566
|
+
: Array.isArray(this.$options.value)
|
|
33567
|
+
? 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']
|
|
33568
|
+
: typeof this.$options.value === 'object' && this.$options.value !== null && 'value' in this.$options.value
|
|
33569
|
+
? [String(this.$options.value.value)] // 케이스 2: {value:'item1', text:'항목1'}
|
|
33570
|
+
: [String(this.$options.value)]; // 기타: 숫자 등
|
|
33571
|
+
this.$options.value = this.$options.flatData.filter((opt) => {
|
|
33572
|
+
const optValue = typeof opt.value === 'string' ? opt.value : String(opt.value);
|
|
33573
|
+
return values.includes(optValue) && opt.text;
|
|
33574
|
+
});
|
|
33466
33575
|
}
|
|
33467
33576
|
else {
|
|
33468
33577
|
this.$options.value = this.$options.flatData.find((opt) => opt.value + '' === this.$options.value + '' && opt.text);
|
|
@@ -36977,26 +37086,8 @@
|
|
|
36977
37086
|
}
|
|
36978
37087
|
this.$event(this, 'onSort', column);
|
|
36979
37088
|
},
|
|
36980
|
-
renderHeader: (columns) => {
|
|
36981
|
-
this
|
|
36982
|
-
!this.$options.readonly &&
|
|
36983
|
-
columns.push({
|
|
36984
|
-
label: this.$options.textSets.orderLabel,
|
|
36985
|
-
key: 'btnOrder',
|
|
36986
|
-
style: {
|
|
36987
|
-
width: '50px'
|
|
36988
|
-
}
|
|
36989
|
-
});
|
|
36990
|
-
this.$options.hasDelete &&
|
|
36991
|
-
!this.$options.readonly &&
|
|
36992
|
-
columns.push({
|
|
36993
|
-
label: this.$options.textSets.deleteLabel,
|
|
36994
|
-
key: 'btnDelete',
|
|
36995
|
-
style: {
|
|
36996
|
-
width: '30px'
|
|
36997
|
-
}
|
|
36998
|
-
});
|
|
36999
|
-
this._setColumnsTemplate();
|
|
37089
|
+
renderHeader: (columns, isReset = false) => {
|
|
37090
|
+
this._setColumnsTemplate(isReset);
|
|
37000
37091
|
return (createElement$1("div", { className: "gn-datagrid-header-row", style: {
|
|
37001
37092
|
'grid-template-columns': this._columnsTemplate.join(' ')
|
|
37002
37093
|
} },
|
|
@@ -37035,6 +37126,10 @@
|
|
|
37035
37126
|
column.draggable && (this.$options.headers ? idx < this.$options.headers.length - 1 : true) && createElement$1("span", { className: "is-handle", "data-index": idx })));
|
|
37036
37127
|
},
|
|
37037
37128
|
renderBody: (data, columns) => {
|
|
37129
|
+
// 헤더가 숨겨진 경우에도 body 렌더 전에 템플릿 폭을 준비한다
|
|
37130
|
+
if (!this._columnsTemplate || !this._columnsTemplate.length) {
|
|
37131
|
+
this._setColumnsTemplate();
|
|
37132
|
+
}
|
|
37038
37133
|
rowIdx$1 = 0;
|
|
37039
37134
|
return (createElement$1("div", { className: "gn-datagrid-body", style: {
|
|
37040
37135
|
maxHeight: this.$options.bodyHeight ? this.$options.bodyHeight : 'auto'
|
|
@@ -37048,7 +37143,6 @@
|
|
|
37048
37143
|
});
|
|
37049
37144
|
},
|
|
37050
37145
|
renderRow: (row, columns, depth = 0, hasChild, isOpened, isCheck = false) => {
|
|
37051
|
-
row._depth = depth;
|
|
37052
37146
|
const _index = rowIdx$1++;
|
|
37053
37147
|
if (row.isChecked) {
|
|
37054
37148
|
isCheck = true;
|
|
@@ -37182,8 +37276,9 @@
|
|
|
37182
37276
|
e.stopPropagation();
|
|
37183
37277
|
toggler = parents(e.currentTarget, '.gn-datagrid-body-row');
|
|
37184
37278
|
}
|
|
37185
|
-
const
|
|
37186
|
-
|
|
37279
|
+
const rowDepth = Number(attr(toggler, 'data-depth')) || 0;
|
|
37280
|
+
const children = nextUntil(toggler, '.gn-datagrid-body-row[data-depth="' + rowDepth + '"]').filter((x) => {
|
|
37281
|
+
return Number(attr(x, 'data-depth')) > rowDepth;
|
|
37187
37282
|
});
|
|
37188
37283
|
type = type ? type : hasClass(toggler, 'is-collapsed') ? 'expand' : 'collapse';
|
|
37189
37284
|
if (type === 'collapse') {
|
|
@@ -37199,7 +37294,7 @@
|
|
|
37199
37294
|
//show childs
|
|
37200
37295
|
removeClass(toggler, 'is-collapsed');
|
|
37201
37296
|
removeClass(children.filter((x) => {
|
|
37202
|
-
return x
|
|
37297
|
+
return Number(attr(x, 'data-depth')) == rowDepth + 1;
|
|
37203
37298
|
}), 'is-hidden');
|
|
37204
37299
|
this.$event(this, 'onToggle', 'expanded', row, index$1(toggler));
|
|
37205
37300
|
}
|
|
@@ -37257,13 +37352,15 @@
|
|
|
37257
37352
|
e.stopPropagation();
|
|
37258
37353
|
const checker = parents(e.currentTarget, '.gn-datagrid-body-row');
|
|
37259
37354
|
const checkerState = e.target.checked;
|
|
37260
|
-
find('.is-allChecker', this.$el)
|
|
37355
|
+
const allChecker = find('.is-allChecker', this.$el);
|
|
37356
|
+
allChecker && (allChecker.checked = false);
|
|
37357
|
+
const rowDepth = Number(attr(checker, 'data-depth')) || 0;
|
|
37261
37358
|
// 1. row에 자식노드가 있는지 확인한다.
|
|
37262
37359
|
if (this.$options.checkCapturing && row[this.$options.childField] && row[this.$options.childField].length) {
|
|
37263
37360
|
// 2. 자식노드가 있는경우 자식 체크박스도 함께 토글한다.
|
|
37264
|
-
nextUntil(checker, '.gn-datagrid-body-row[data-depth="' +
|
|
37361
|
+
nextUntil(checker, '.gn-datagrid-body-row[data-depth="' + rowDepth + '"]')
|
|
37265
37362
|
.filter((x) => {
|
|
37266
|
-
return x
|
|
37363
|
+
return Number(attr(x, 'data-depth')) > rowDepth;
|
|
37267
37364
|
})
|
|
37268
37365
|
.forEach((x) => {
|
|
37269
37366
|
const _checker = find('.is-rowChecker', x);
|
|
@@ -37273,17 +37370,17 @@
|
|
|
37273
37370
|
});
|
|
37274
37371
|
}
|
|
37275
37372
|
// 3. 체크 해제인 경우만 부모노드가 있는지 확인한다.
|
|
37276
|
-
if (this.$options.checkCapturing &&
|
|
37373
|
+
if (this.$options.checkCapturing && rowDepth > 0 && !checkerState) {
|
|
37277
37374
|
// 4. 부모노드가 체크되어 있는지 확인한다
|
|
37278
37375
|
const exeDepth = [];
|
|
37279
37376
|
prevUntil(checker, '.gn-datagrid-body-row[data-depth="0"]')
|
|
37280
37377
|
.filter((x) => {
|
|
37281
|
-
const _thisDepth = x
|
|
37378
|
+
const _thisDepth = attr(x, 'data-depth');
|
|
37282
37379
|
if (exeDepth.includes(_thisDepth)) {
|
|
37283
37380
|
return false;
|
|
37284
37381
|
}
|
|
37285
37382
|
exeDepth.push(_thisDepth);
|
|
37286
|
-
return _thisDepth <
|
|
37383
|
+
return Number(_thisDepth) < rowDepth;
|
|
37287
37384
|
})
|
|
37288
37385
|
.forEach((x) => {
|
|
37289
37386
|
const _checker = find('.is-rowChecker', x);
|
|
@@ -37299,9 +37396,21 @@
|
|
|
37299
37396
|
if (hasCheck === undefined) {
|
|
37300
37397
|
hasCheck = this.$options.hasCheck;
|
|
37301
37398
|
}
|
|
37302
|
-
this.$options.headers
|
|
37399
|
+
const prevHeaders = [...(this.$options.headers || [])];
|
|
37400
|
+
// _prepareHeaders가 배열을 변경하므로 비교용(prevHeaders)과 가공용(baseHeaders)을 분리한다
|
|
37401
|
+
const baseHeaders = headers ? [...headers] : [...prevHeaders];
|
|
37402
|
+
const preparedHeaders = this._prepareHeaders(baseHeaders);
|
|
37403
|
+
// 헤더 배열의 내용(길이, key)이 바뀐 경우에만 DOM 기반 폭 계산을 리셋한다
|
|
37404
|
+
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); });
|
|
37303
37405
|
this.$options.hasCheck = hasCheck;
|
|
37304
|
-
|
|
37406
|
+
const headerRow = find('.gn-datagrid-header-row', this.$el);
|
|
37407
|
+
// 헤더가 없을 때도 컬럼 수/폭 변경을 반영하기 위해 템플릿을 갱신한다
|
|
37408
|
+
if (this.$options.hasHeader && headerRow) {
|
|
37409
|
+
this.$template.reRender(headerRow, this._hidden.renderHeader(preparedHeaders, isReset));
|
|
37410
|
+
}
|
|
37411
|
+
else {
|
|
37412
|
+
this._setColumnsTemplate(isReset);
|
|
37413
|
+
}
|
|
37305
37414
|
this._hidden.resetData(data ? arrClone(data) : this.$options.data);
|
|
37306
37415
|
this.$render(this.$options);
|
|
37307
37416
|
isFunction(resolve) && resolve();
|
|
@@ -37316,6 +37425,10 @@
|
|
|
37316
37425
|
});
|
|
37317
37426
|
},
|
|
37318
37427
|
awaitData: (data) => {
|
|
37428
|
+
// asyncData 콜백 실행 중 컴포넌트가 destroy된 경우 안전하게 종료
|
|
37429
|
+
if (!this.$options || !this._hidden) {
|
|
37430
|
+
return;
|
|
37431
|
+
}
|
|
37319
37432
|
if (this.$options.asyncData && this.$options.paginator && !this._paginator) {
|
|
37320
37433
|
this._paginator = new Pagination('pagination', find('.gn-datagrid-footer', this.$el), {
|
|
37321
37434
|
total: this.$options.paginator.total || 0,
|
|
@@ -37340,7 +37453,8 @@
|
|
|
37340
37453
|
this._fixCellStyleOnDraggable();
|
|
37341
37454
|
// 체크박스가 있는경우 전체 체크항목을 해제해준다
|
|
37342
37455
|
if (this.$options.hasCheck) {
|
|
37343
|
-
find('.is-allChecker', this.$el)
|
|
37456
|
+
const allChecker = find('.is-allChecker', this.$el);
|
|
37457
|
+
allChecker && (allChecker.checked = false);
|
|
37344
37458
|
}
|
|
37345
37459
|
isFunction(resolve) && resolve();
|
|
37346
37460
|
});
|
|
@@ -37375,8 +37489,18 @@
|
|
|
37375
37489
|
stopRowSelectEvent: (e) => {
|
|
37376
37490
|
e.stopPropagation();
|
|
37377
37491
|
},
|
|
37378
|
-
deleteRow: (index) => {
|
|
37379
|
-
|
|
37492
|
+
deleteRow: async (index) => {
|
|
37493
|
+
var _a;
|
|
37494
|
+
const confirmMessage = (_a = this.$options.textSets) === null || _a === void 0 ? void 0 : _a.deleteConfirmMessage;
|
|
37495
|
+
if (confirmMessage && !window.confirm(confirmMessage)) {
|
|
37496
|
+
return;
|
|
37497
|
+
}
|
|
37498
|
+
const removedData = this._hidden.findData(index);
|
|
37499
|
+
const cancelled = await this.$event(this, 'onDelete', removedData, index);
|
|
37500
|
+
if (cancelled) {
|
|
37501
|
+
return;
|
|
37502
|
+
}
|
|
37503
|
+
this._hidden.deleteData(index);
|
|
37380
37504
|
this._hidden.resetData(this.$options.data);
|
|
37381
37505
|
this.$event(this, 'onChange', this.$options.data);
|
|
37382
37506
|
},
|
|
@@ -37411,22 +37535,38 @@
|
|
|
37411
37535
|
col.offHover && col.offHover.call(this, row, col, index, e);
|
|
37412
37536
|
},
|
|
37413
37537
|
findData: (index) => {
|
|
37414
|
-
|
|
37415
|
-
|
|
37416
|
-
|
|
37417
|
-
|
|
37418
|
-
|
|
37538
|
+
return this._hidden.walkByIndex(index, 'find');
|
|
37539
|
+
},
|
|
37540
|
+
deleteData: (index) => {
|
|
37541
|
+
return this._hidden.walkByIndex(index, 'delete');
|
|
37542
|
+
},
|
|
37543
|
+
walkByIndex: (index, action) => {
|
|
37544
|
+
let deter = 0;
|
|
37545
|
+
let result = null;
|
|
37546
|
+
const findIndex = (datas) => {
|
|
37547
|
+
for (let i = 0; i < datas.length; i++) {
|
|
37548
|
+
if (deter === index) {
|
|
37549
|
+
switch (action) {
|
|
37550
|
+
case 'find':
|
|
37551
|
+
result = datas[i];
|
|
37552
|
+
break;
|
|
37553
|
+
case 'delete':
|
|
37554
|
+
result = datas.splice(i, 1)[0];
|
|
37555
|
+
break;
|
|
37556
|
+
}
|
|
37419
37557
|
return true;
|
|
37420
37558
|
}
|
|
37421
|
-
|
|
37422
|
-
|
|
37423
|
-
|
|
37559
|
+
deter++;
|
|
37560
|
+
const children = datas[i][this.$options.childField];
|
|
37561
|
+
if (Array.isArray(children) && children.length) {
|
|
37562
|
+
if (findIndex(children))
|
|
37563
|
+
return true;
|
|
37424
37564
|
}
|
|
37425
|
-
|
|
37426
|
-
|
|
37565
|
+
}
|
|
37566
|
+
return false;
|
|
37427
37567
|
};
|
|
37428
|
-
findIndex(this.$options.data
|
|
37429
|
-
return
|
|
37568
|
+
findIndex(this.$options.data);
|
|
37569
|
+
return result;
|
|
37430
37570
|
},
|
|
37431
37571
|
getChecked: () => {
|
|
37432
37572
|
return findAll('.is-rowChecker', this.$el)
|
|
@@ -37513,11 +37653,13 @@
|
|
|
37513
37653
|
hasOrder: false,
|
|
37514
37654
|
hasDelete: false,
|
|
37515
37655
|
isEllipsis: false,
|
|
37656
|
+
hasHeader: true,
|
|
37516
37657
|
data: [],
|
|
37517
37658
|
textSets: {
|
|
37518
37659
|
noData: 'No records available.',
|
|
37519
37660
|
orderLabel: '',
|
|
37520
|
-
deleteLabel: ''
|
|
37661
|
+
deleteLabel: '',
|
|
37662
|
+
deleteConfirmMessage: ''
|
|
37521
37663
|
},
|
|
37522
37664
|
childField: 'child',
|
|
37523
37665
|
checkCapturing: true,
|
|
@@ -37535,7 +37677,8 @@
|
|
|
37535
37677
|
onCheck: true,
|
|
37536
37678
|
onDoubleClick: true,
|
|
37537
37679
|
onChange: true,
|
|
37538
|
-
onDragEnd: true
|
|
37680
|
+
onDragEnd: true,
|
|
37681
|
+
onDelete: true
|
|
37539
37682
|
};
|
|
37540
37683
|
this.methods = {
|
|
37541
37684
|
reRender(options) {
|
|
@@ -37595,18 +37738,21 @@
|
|
|
37595
37738
|
this.$selector = this.$selector;
|
|
37596
37739
|
this.$init(this, options);
|
|
37597
37740
|
}
|
|
37598
|
-
_setColumnsTemplate() {
|
|
37741
|
+
_setColumnsTemplate(isReset = false) {
|
|
37599
37742
|
// header cell의 각 넓이를 배열로 가져온다
|
|
37600
37743
|
// ! 모든 컬럼의 넓이가 지정된 경우 이동(btnOrder), 삭제(btnDelete) 컬럼을 제외한 마지막 컬럼은 1fr로 고정
|
|
37601
37744
|
const _isfixedAllWidth = this.$options.headers.every((header) => { var _a; return ((_a = header.style) === null || _a === void 0 ? void 0 : _a.width) !== undefined; });
|
|
37602
37745
|
const _fixedTemplateColumn = this.$options.headers.findLast((header) => !this._isSystemAddedColumn(header.key) && !header.isHidden);
|
|
37746
|
+
// 헤더 DOM이 없거나 모든 일반 컬럼이 숨겨진 경우에도 안전하게 비교할 수 있도록 key만 옵셔널하게 캐싱한다
|
|
37747
|
+
const _fixedTemplateKey = _fixedTemplateColumn === null || _fixedTemplateColumn === void 0 ? void 0 : _fixedTemplateColumn.key;
|
|
37603
37748
|
const columns = findAll('.gn-datagrid-header-cell', this.$el);
|
|
37604
|
-
|
|
37749
|
+
// isReset이면 기존 DOM 폭을 재사용하지 않고 헤더 정의로 재계산
|
|
37750
|
+
if (this.$el && columns.length && !isReset) {
|
|
37605
37751
|
this._columnsTemplate = findAll('.gn-datagrid-header-cell', this.$el).map((header, idx) => {
|
|
37606
37752
|
if (this.$options.headers[idx].isHidden) {
|
|
37607
37753
|
return '';
|
|
37608
37754
|
}
|
|
37609
|
-
else if (_isfixedAllWidth && this.$options.headers[idx].key ===
|
|
37755
|
+
else if (_isfixedAllWidth && _fixedTemplateKey && this.$options.headers[idx].key === _fixedTemplateKey) {
|
|
37610
37756
|
return '1fr';
|
|
37611
37757
|
}
|
|
37612
37758
|
else {
|
|
@@ -37620,7 +37766,7 @@
|
|
|
37620
37766
|
if (header.isHidden) {
|
|
37621
37767
|
return '';
|
|
37622
37768
|
}
|
|
37623
|
-
else if (_isfixedAllWidth && header.key ===
|
|
37769
|
+
else if (_isfixedAllWidth && _fixedTemplateKey && header.key === _fixedTemplateKey) {
|
|
37624
37770
|
return '1fr';
|
|
37625
37771
|
}
|
|
37626
37772
|
else {
|
|
@@ -37641,18 +37787,45 @@
|
|
|
37641
37787
|
_isSystemAddedColumn(key) {
|
|
37642
37788
|
return ['btnOrder', 'btnDelete'].includes(key);
|
|
37643
37789
|
}
|
|
37790
|
+
// 옵션에 따른 추가 해더 구성
|
|
37791
|
+
_prepareHeaders(headers = []) {
|
|
37792
|
+
const hasOrderColumn = headers.some((header) => header.key === 'btnOrder');
|
|
37793
|
+
const hasDeleteColumn = headers.some((header) => header.key === 'btnDelete');
|
|
37794
|
+
if (this.$options.hasOrder && !this.$options.readonly && !hasOrderColumn) {
|
|
37795
|
+
headers.push({
|
|
37796
|
+
label: this.$options.textSets.orderLabel,
|
|
37797
|
+
key: 'btnOrder',
|
|
37798
|
+
style: {
|
|
37799
|
+
width: '50px'
|
|
37800
|
+
}
|
|
37801
|
+
});
|
|
37802
|
+
}
|
|
37803
|
+
if (this.$options.hasDelete && !this.$options.readonly && !hasDeleteColumn) {
|
|
37804
|
+
headers.push({
|
|
37805
|
+
label: this.$options.textSets.deleteLabel,
|
|
37806
|
+
key: 'btnDelete',
|
|
37807
|
+
style: {
|
|
37808
|
+
width: '30px'
|
|
37809
|
+
}
|
|
37810
|
+
});
|
|
37811
|
+
}
|
|
37812
|
+
this.$options.headers = headers;
|
|
37813
|
+
return headers;
|
|
37814
|
+
}
|
|
37644
37815
|
template(config) {
|
|
37645
37816
|
const styles = {};
|
|
37817
|
+
const headers = this._prepareHeaders(config.headers);
|
|
37646
37818
|
return (createElement$1("div", { id: this._uid, className: 'gn-datagrid' +
|
|
37647
37819
|
(config.style ? ' is-' + config.style : '') +
|
|
37648
37820
|
(config.isEllipsis ? ' is-ellipsis' : '') +
|
|
37649
37821
|
(config.bodyHeight ? ' has-fixed-body' : '') +
|
|
37650
37822
|
(config.fixHeader ? ' has-fixed-header' : '') +
|
|
37651
37823
|
(config.fixFooter ? ' has-fixed-footer' : '') +
|
|
37824
|
+
(!config.hasHeader ? ' is-headless' : '') +
|
|
37652
37825
|
(config.data.some((d) => isArray$1(d[this.$options.childField])) ? ' has-left-padding' : '') +
|
|
37653
37826
|
(config.disabled ? ' is-disabled' : ''), style: styles },
|
|
37654
|
-
createElement$1("div", { className: "gn-datagrid-header" }, this._hidden.renderHeader(
|
|
37655
|
-
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),
|
|
37827
|
+
config.hasHeader && createElement$1("div", { className: "gn-datagrid-header" }, this._hidden.renderHeader(headers)),
|
|
37828
|
+
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)),
|
|
37656
37829
|
config.paginator /* 페이지네이터 옵션 확인 */ && createElement$1("div", { className: "gn-datagrid-footer" })));
|
|
37657
37830
|
}
|
|
37658
37831
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -37669,18 +37842,20 @@
|
|
|
37669
37842
|
}
|
|
37670
37843
|
}
|
|
37671
37844
|
completed() {
|
|
37672
|
-
if (this.$options.fixHeader) {
|
|
37845
|
+
if (this.$options.fixHeader && this.$options.hasHeader) {
|
|
37673
37846
|
const body = find('.gn-datagrid-contents', this.$el);
|
|
37674
37847
|
const header = find('.gn-datagrid-header', this.$el);
|
|
37675
|
-
|
|
37676
|
-
|
|
37677
|
-
|
|
37848
|
+
if (header) {
|
|
37849
|
+
const _offset = offset(header);
|
|
37850
|
+
this.$options.bodyTopMargin = _offset.height ? _offset.height - 1 + 'px' : '2.4rem';
|
|
37851
|
+
css$1(body, 'margin-top', this.$options.bodyTopMargin);
|
|
37852
|
+
}
|
|
37678
37853
|
if (this.$options.paginator) {
|
|
37679
37854
|
this.$options.bodyBottomMargin = '2.4rem';
|
|
37680
37855
|
css$1(body, 'margin-bottom', this.$options.bodyBottomMargin);
|
|
37681
37856
|
}
|
|
37682
37857
|
}
|
|
37683
|
-
if (this.$options.fixHeader || this.$options.bodyHeight) {
|
|
37858
|
+
if ((this.$options.fixHeader && this.$options.hasHeader) || this.$options.bodyHeight) {
|
|
37684
37859
|
this._hidden.setBlankHeader();
|
|
37685
37860
|
on(window, 'resize', this._hidden.setBlankHeader);
|
|
37686
37861
|
}
|
|
@@ -39025,7 +39200,9 @@
|
|
|
39025
39200
|
super(name, selector, options);
|
|
39026
39201
|
this._hidden = {
|
|
39027
39202
|
open: () => {
|
|
39028
|
-
|
|
39203
|
+
if (!this.$options.disabled) {
|
|
39204
|
+
addClass(this.$el, 'is-open');
|
|
39205
|
+
}
|
|
39029
39206
|
},
|
|
39030
39207
|
close: () => {
|
|
39031
39208
|
removeClass(this.$el, 'is-open');
|
|
@@ -39037,6 +39214,62 @@
|
|
|
39037
39214
|
changeText: (buttonText) => {
|
|
39038
39215
|
this.$options.textSets.buttonText = buttonText;
|
|
39039
39216
|
html(find('.menuButton-text', this.$el), buttonText);
|
|
39217
|
+
},
|
|
39218
|
+
disable: () => {
|
|
39219
|
+
this.$options.disabled = true;
|
|
39220
|
+
const buttonEl = find('button', this.$el);
|
|
39221
|
+
if (buttonEl) {
|
|
39222
|
+
attr(buttonEl, 'disabled', true);
|
|
39223
|
+
}
|
|
39224
|
+
addClass(this.$el, 'is-disabled');
|
|
39225
|
+
this._hidden.close();
|
|
39226
|
+
},
|
|
39227
|
+
enable: () => {
|
|
39228
|
+
this.$options.disabled = false;
|
|
39229
|
+
const buttonEl = find('button', this.$el);
|
|
39230
|
+
if (buttonEl) {
|
|
39231
|
+
removeAttr(buttonEl, 'disabled');
|
|
39232
|
+
}
|
|
39233
|
+
removeClass(this.$el, 'is-disabled');
|
|
39234
|
+
},
|
|
39235
|
+
renderMenus: (menus, depth = 0, parentPath = '') => {
|
|
39236
|
+
return (createElement$1("ul", { className: depth > 0 ? 'menuButton-submenu' : '' }, menus.map((menu, index) => {
|
|
39237
|
+
const hasChild = menu.child && isArray$1(menu.child) && menu.child.length > 0;
|
|
39238
|
+
const hasHtml = !!menu.html;
|
|
39239
|
+
// html이 있으면 innerHTML이 모든 자식 요소를 덮어쓰므로 서브메뉴를 렌더링하지 않음
|
|
39240
|
+
const canRenderChild = hasChild && depth < 2 && !hasHtml; // 최대 2단계까지만 허용
|
|
39241
|
+
const isDisabled = menu.disabled === true;
|
|
39242
|
+
const isActived = menu.actived === true;
|
|
39243
|
+
// 부모 경로를 포함한 고유한 ID 생성
|
|
39244
|
+
const currentPath = parentPath ? `${parentPath}-${index}` : `${index}`;
|
|
39245
|
+
const uniqueId = `${this._uid}-${currentPath}`;
|
|
39246
|
+
return (createElement$1("li", { id: uniqueId, className: 'menuButton-menu' +
|
|
39247
|
+
(this.$options.align ? ' has-text-' + this.$options.align : '') +
|
|
39248
|
+
(canRenderChild ? ' has-submenu' : '') +
|
|
39249
|
+
(depth > 0 ? ' is-submenu-item' : '') +
|
|
39250
|
+
(isDisabled ? ' is-disabled' : '') +
|
|
39251
|
+
(isActived ? ' is-actived' : ''), "on-click": (e) => {
|
|
39252
|
+
// disabled 상태이거나 자식 메뉴가 있는 경우 클릭 이벤트 처리하지 않음
|
|
39253
|
+
if (isDisabled) {
|
|
39254
|
+
e.stopPropagation();
|
|
39255
|
+
e.preventDefault();
|
|
39256
|
+
return;
|
|
39257
|
+
}
|
|
39258
|
+
// 자식 메뉴가 없는 경우에만 select 이벤트 발생
|
|
39259
|
+
if (!canRenderChild) {
|
|
39260
|
+
e.stopPropagation();
|
|
39261
|
+
this._hidden.select.call(this, menu, e);
|
|
39262
|
+
}
|
|
39263
|
+
}, innerHTML: hasHtml ? menu.html : '' },
|
|
39264
|
+
hasHtml ? ('') : (createElement$1("span", { className: "menuButton-menu-content" },
|
|
39265
|
+
createElement$1("span", { className: "menuButton-menu-text" }, menu.text),
|
|
39266
|
+
canRenderChild && (createElement$1("span", { className: "menuButton-menu-arrow" },
|
|
39267
|
+
createElement$1("i", { className: "fas fa-caret-right" }))))),
|
|
39268
|
+
canRenderChild && this._hidden.renderMenus.call(this, menu.child, depth + 1, currentPath)));
|
|
39269
|
+
})));
|
|
39270
|
+
},
|
|
39271
|
+
renderSub: (data) => {
|
|
39272
|
+
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));
|
|
39040
39273
|
}
|
|
39041
39274
|
};
|
|
39042
39275
|
this.config = {
|
|
@@ -39056,6 +39289,19 @@
|
|
|
39056
39289
|
},
|
|
39057
39290
|
buttonText(text) {
|
|
39058
39291
|
this._hidden.changeText(text);
|
|
39292
|
+
},
|
|
39293
|
+
reRender(data) {
|
|
39294
|
+
this.$options.data = data;
|
|
39295
|
+
const menuMenusEl = find('.menuButton-menus > div', this.$el);
|
|
39296
|
+
if (menuMenusEl && this.$template) {
|
|
39297
|
+
this.$template.reRender(menuMenusEl, this._hidden.renderSub.call(this, data));
|
|
39298
|
+
}
|
|
39299
|
+
},
|
|
39300
|
+
disabled() {
|
|
39301
|
+
this._hidden.disable();
|
|
39302
|
+
},
|
|
39303
|
+
enabled() {
|
|
39304
|
+
this._hidden.enable();
|
|
39059
39305
|
}
|
|
39060
39306
|
};
|
|
39061
39307
|
this.$selector = this.$selector;
|
|
@@ -39066,23 +39312,19 @@
|
|
|
39066
39312
|
if (config.width) {
|
|
39067
39313
|
styles.width = getUnit('width', config.width);
|
|
39068
39314
|
}
|
|
39069
|
-
|
|
39070
|
-
|
|
39071
|
-
|
|
39072
|
-
|
|
39073
|
-
|
|
39074
|
-
|
|
39075
|
-
return createElement$1("div", null, isArray$1(data) && data.length && isArray$1(data[0]) ? data.map((menus) => renderMenus(menus)) : renderMenus(data));
|
|
39076
|
-
};
|
|
39077
|
-
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 },
|
|
39078
|
-
createElement$1("button", { type: "button", className: config.align ? 'has-text-' + config.align : '', "on-click": this._hidden.open },
|
|
39315
|
+
return (createElement$1("div", { id: this._uid, className: 'gn-menuButton' +
|
|
39316
|
+
(config.color ? ' is-' + config.color : '') +
|
|
39317
|
+
(config.style ? ' is-' + config.style : '') +
|
|
39318
|
+
(config.size ? ' is-' + config.size : '') +
|
|
39319
|
+
(config.disabled ? ' is-disabled' : ''), style: styles },
|
|
39320
|
+
createElement$1("button", { type: "button", className: config.align ? 'has-text-' + config.align : '', disabled: config.disabled, "on-click": this._hidden.open },
|
|
39079
39321
|
config.icon && (createElement$1("span", { className: 'gn-icon is-' + (config.size === 'large' ? 'medium' : config.size === 'medium' ? 'normal' : 'small') },
|
|
39080
39322
|
createElement$1("i", { className: 'fas fa-' + config.icon }),
|
|
39081
39323
|
' ')),
|
|
39082
39324
|
createElement$1("span", { className: "gn-icon is-small menuButton-icon" },
|
|
39083
39325
|
createElement$1("i", { className: "fas fa-caret-down" })),
|
|
39084
39326
|
createElement$1("span", { className: "menuButton-text" }, config.textSets.buttonText)),
|
|
39085
|
-
createElement$1("div", { className: "menuButton-menus" }, renderSub(config.data))));
|
|
39327
|
+
createElement$1("div", { className: "menuButton-menus" }, this._hidden.renderSub.call(this, config.data))));
|
|
39086
39328
|
}
|
|
39087
39329
|
completed() {
|
|
39088
39330
|
// 해당 컴포넌트 외 클릭 시 menu panel 숨김
|
|
@@ -39293,6 +39535,7 @@
|
|
|
39293
39535
|
}
|
|
39294
39536
|
}
|
|
39295
39537
|
|
|
39538
|
+
library$1.add(icons$1, icons);
|
|
39296
39539
|
class Picklist extends GNCoreInstance {
|
|
39297
39540
|
constructor(name, selector, options = {}) {
|
|
39298
39541
|
super(name, selector, options);
|
|
@@ -39434,17 +39677,26 @@
|
|
|
39434
39677
|
},
|
|
39435
39678
|
renderSub: (item) => {
|
|
39436
39679
|
const items = this.$options.data[item] || [];
|
|
39437
|
-
return (createElement$1("ul", null, items.map((option, index) =>
|
|
39438
|
-
|
|
39439
|
-
|
|
39440
|
-
|
|
39441
|
-
|
|
39442
|
-
|
|
39443
|
-
|
|
39680
|
+
return (createElement$1("ul", null, items.map((option, index) => {
|
|
39681
|
+
var _a;
|
|
39682
|
+
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
|
|
39683
|
+
? null
|
|
39684
|
+
: this._hidden.move.bind(this, item === 'source' ? 'add' : 'remove', [
|
|
39685
|
+
{
|
|
39686
|
+
value: option.value,
|
|
39687
|
+
text: option.text,
|
|
39688
|
+
html: (_a = option.html) !== null && _a !== void 0 ? _a : null
|
|
39689
|
+
}
|
|
39690
|
+
]) },
|
|
39691
|
+
createElement$1("span", { className: "dropdown-text", innerHTML: option.html ? option.html : '' }, option.html ? ('') : option.icon ? (createElement$1("span", null,
|
|
39692
|
+
createElement$1("span", { className: 'gn-icon' + (this.$options.size ? ' is-' + this.$options.size : '') },
|
|
39693
|
+
createElement$1("i", { className: (this.isBrandIcon(option.icon) ? 'fab' : 'fa') + ` fa-${option.icon}` })),
|
|
39694
|
+
escapeEntity(option.text))) : (escapeEntity(option.text)))));
|
|
39695
|
+
})));
|
|
39444
39696
|
},
|
|
39445
39697
|
getSelection: (target) => {
|
|
39446
39698
|
return findAll('.is-active', this.$options.delegates[target]).map((select) => {
|
|
39447
|
-
return
|
|
39699
|
+
return this.$options.data[target].find((option) => option.value === attr(select, 'data-value'));
|
|
39448
39700
|
});
|
|
39449
39701
|
},
|
|
39450
39702
|
disable: () => {
|
|
@@ -39604,6 +39856,11 @@
|
|
|
39604
39856
|
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'))));
|
|
39605
39857
|
}
|
|
39606
39858
|
}
|
|
39859
|
+
isBrandIcon(iconName) {
|
|
39860
|
+
const iconLookup = { prefix: 'fab', iconName: iconName };
|
|
39861
|
+
const iconDefinition = findIconDefinition$1(iconLookup);
|
|
39862
|
+
return iconDefinition !== undefined;
|
|
39863
|
+
}
|
|
39607
39864
|
}
|
|
39608
39865
|
|
|
39609
39866
|
class Progressbar extends GNCoreInstance {
|
|
@@ -39762,6 +40019,409 @@
|
|
|
39762
40019
|
}
|
|
39763
40020
|
}
|
|
39764
40021
|
|
|
40022
|
+
const CLASS_DRAGGING = 'is-dragging';
|
|
40023
|
+
const CLASS_GROUP_DRAGGING = 'is-group-dragging';
|
|
40024
|
+
const CLASS_DRAG_OVER_TOP = 'is-drag-over-top';
|
|
40025
|
+
const CLASS_DRAG_OVER_BOTTOM = 'is-drag-over-bottom';
|
|
40026
|
+
const DEFAULT_NO_DATA = 'No records available.';
|
|
40027
|
+
const DRAG_STATE_CLASSES = [CLASS_DRAGGING, CLASS_GROUP_DRAGGING, CLASS_DRAG_OVER_TOP, CLASS_DRAG_OVER_BOTTOM];
|
|
40028
|
+
class SortableList extends GNCoreInstance {
|
|
40029
|
+
constructor(name, selector, options = {}) {
|
|
40030
|
+
super(name, selector, options);
|
|
40031
|
+
this._dragging = null;
|
|
40032
|
+
this._selection = new Set();
|
|
40033
|
+
this.DRAG_IMAGE_OFFSET_X = 0;
|
|
40034
|
+
this.DRAG_IMAGE_OFFSET_Y = 0;
|
|
40035
|
+
this.DRAG_OVER_THRESHOLD_RATIO = 0.5;
|
|
40036
|
+
this._hidden = {
|
|
40037
|
+
toggle: (e) => {
|
|
40038
|
+
if (this.$options.disabled) {
|
|
40039
|
+
return;
|
|
40040
|
+
}
|
|
40041
|
+
const value = attr(e.currentTarget, 'data-value');
|
|
40042
|
+
const hasItem = this.$options.data.some((option) => option.value === value);
|
|
40043
|
+
if (!value || !hasItem) {
|
|
40044
|
+
return;
|
|
40045
|
+
}
|
|
40046
|
+
if (this._selection.has(value)) {
|
|
40047
|
+
this._selection.delete(value);
|
|
40048
|
+
removeClass(e.currentTarget, 'is-active');
|
|
40049
|
+
}
|
|
40050
|
+
else {
|
|
40051
|
+
this._selection.add(value);
|
|
40052
|
+
addClass(e.currentTarget, 'is-active');
|
|
40053
|
+
}
|
|
40054
|
+
},
|
|
40055
|
+
sort: (dir) => {
|
|
40056
|
+
const items = this.$options.data || [];
|
|
40057
|
+
const selected = this._hidden.getSelection();
|
|
40058
|
+
if (!selected.length || selected.length === items.length) {
|
|
40059
|
+
return;
|
|
40060
|
+
}
|
|
40061
|
+
const selectedValues = new Set(selected.map((item) => item.value));
|
|
40062
|
+
// dir: up/down → 이동, up-all/down-all → 맨 위/맨 아래로 보내기
|
|
40063
|
+
if (dir.indexOf('all') > -1) {
|
|
40064
|
+
this.$options.data = items.slice().sort((a, b) => {
|
|
40065
|
+
const _sort = dir === 'up-all' ? -1 : 1;
|
|
40066
|
+
const aSel = selectedValues.has(a.value);
|
|
40067
|
+
const bSel = selectedValues.has(b.value);
|
|
40068
|
+
if (aSel && bSel) {
|
|
40069
|
+
return 0;
|
|
40070
|
+
}
|
|
40071
|
+
else if (aSel) {
|
|
40072
|
+
return _sort;
|
|
40073
|
+
}
|
|
40074
|
+
else if (bSel) {
|
|
40075
|
+
return _sort * -1;
|
|
40076
|
+
}
|
|
40077
|
+
return 0;
|
|
40078
|
+
});
|
|
40079
|
+
}
|
|
40080
|
+
else {
|
|
40081
|
+
if (dir === 'up') {
|
|
40082
|
+
const reordered = items.slice();
|
|
40083
|
+
// 한 번에 한 칸씩만 올려 상대 순서를 유지한다
|
|
40084
|
+
for (let i = 1; i < reordered.length; i++) {
|
|
40085
|
+
if (!selectedValues.has(reordered[i].value) || selectedValues.has(reordered[i - 1].value)) {
|
|
40086
|
+
continue;
|
|
40087
|
+
}
|
|
40088
|
+
const temp = reordered[i - 1];
|
|
40089
|
+
reordered[i - 1] = reordered[i];
|
|
40090
|
+
reordered[i] = temp;
|
|
40091
|
+
}
|
|
40092
|
+
this.$options.data = reordered;
|
|
40093
|
+
}
|
|
40094
|
+
else {
|
|
40095
|
+
let reordered = [];
|
|
40096
|
+
let itemsToMoveDown = [];
|
|
40097
|
+
items.forEach((option) => {
|
|
40098
|
+
// reordered: 최종 순서를 쌓는 버퍼, itemsToMoveDown: 아래로 밀어야 할 선택 항목 임시 저장
|
|
40099
|
+
// 비선택 항목은 흐름대로 push, 선택 항목은 dir에 따라 위/아래로 밀어 넣음
|
|
40100
|
+
if (!selectedValues.has(option.value)) {
|
|
40101
|
+
reordered.push(option);
|
|
40102
|
+
if (itemsToMoveDown.length) {
|
|
40103
|
+
reordered = reordered.concat(itemsToMoveDown);
|
|
40104
|
+
itemsToMoveDown = [];
|
|
40105
|
+
}
|
|
40106
|
+
}
|
|
40107
|
+
else if (dir === 'down') {
|
|
40108
|
+
itemsToMoveDown.push(option);
|
|
40109
|
+
}
|
|
40110
|
+
});
|
|
40111
|
+
if (itemsToMoveDown.length) {
|
|
40112
|
+
reordered = reordered.concat(itemsToMoveDown);
|
|
40113
|
+
itemsToMoveDown = [];
|
|
40114
|
+
}
|
|
40115
|
+
this.$options.data = reordered.slice();
|
|
40116
|
+
}
|
|
40117
|
+
}
|
|
40118
|
+
this._hidden.reRender();
|
|
40119
|
+
this._hidden.updateControls();
|
|
40120
|
+
this.$event(this, 'onChange', this.$options.data);
|
|
40121
|
+
},
|
|
40122
|
+
renderSub: () => {
|
|
40123
|
+
var _a, _b;
|
|
40124
|
+
const items = this.$options.data || [];
|
|
40125
|
+
const hasCols = items.some((item) => isArray$1(item.cols) && item.cols.length);
|
|
40126
|
+
if (!items.length) {
|
|
40127
|
+
return (createElement$1("ul", { className: "sortablelist-rows" },
|
|
40128
|
+
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)));
|
|
40129
|
+
}
|
|
40130
|
+
return (createElement$1("ul", { className: 'sortablelist-rows' + (hasCols ? ' is-cols' : '') }, items.map((option, index) => {
|
|
40131
|
+
var _a;
|
|
40132
|
+
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)))));
|
|
40133
|
+
})));
|
|
40134
|
+
},
|
|
40135
|
+
getSelection: () => {
|
|
40136
|
+
return this.$options.data.filter((option) => this._selection.has(option.value));
|
|
40137
|
+
},
|
|
40138
|
+
reRender: () => {
|
|
40139
|
+
const listContainer = find('ul', this.$options.delegates.list);
|
|
40140
|
+
listContainer && this.$template.reRender(listContainer, this._hidden.renderSub());
|
|
40141
|
+
},
|
|
40142
|
+
syncSelection: () => {
|
|
40143
|
+
const values = new Set(this.$options.data.map((item) => item.value));
|
|
40144
|
+
this._selection.forEach(val => {
|
|
40145
|
+
if (!values.has(val)) {
|
|
40146
|
+
this._selection.delete(val);
|
|
40147
|
+
}
|
|
40148
|
+
});
|
|
40149
|
+
},
|
|
40150
|
+
hydrateSelection: (items) => {
|
|
40151
|
+
this._selection.clear();
|
|
40152
|
+
items.forEach((item) => {
|
|
40153
|
+
if (item.selected) {
|
|
40154
|
+
this._selection.add(item.value);
|
|
40155
|
+
}
|
|
40156
|
+
});
|
|
40157
|
+
},
|
|
40158
|
+
validateData: (items) => {
|
|
40159
|
+
if (!isArray$1(items)) {
|
|
40160
|
+
throw new TypeError('Invalid SortableList data: data must be an array');
|
|
40161
|
+
}
|
|
40162
|
+
const seen = new Set();
|
|
40163
|
+
items.forEach((item) => {
|
|
40164
|
+
if (!item || typeof item.value !== 'string') {
|
|
40165
|
+
throw new TypeError('Invalid SortableList data: value must be string');
|
|
40166
|
+
}
|
|
40167
|
+
if (item.value === '') {
|
|
40168
|
+
throw new TypeError('Invalid SortableList data: value cannot be empty');
|
|
40169
|
+
}
|
|
40170
|
+
if (seen.has(item.value)) {
|
|
40171
|
+
throw new TypeError(`Invalid SortableList data: duplicate value '${item.value}'`);
|
|
40172
|
+
}
|
|
40173
|
+
seen.add(item.value);
|
|
40174
|
+
});
|
|
40175
|
+
},
|
|
40176
|
+
updateControls: () => {
|
|
40177
|
+
const hasData = (this.$options.data || []).length > 0;
|
|
40178
|
+
const disableButtons = this.$options.disabled || !hasData;
|
|
40179
|
+
if (disableButtons) {
|
|
40180
|
+
attr(findAll('button', this.$el), 'disabled', true);
|
|
40181
|
+
}
|
|
40182
|
+
else {
|
|
40183
|
+
removeAttr(findAll('button', this.$el), 'disabled');
|
|
40184
|
+
}
|
|
40185
|
+
if (!hasData) {
|
|
40186
|
+
addClass(this.$el, 'is-empty');
|
|
40187
|
+
}
|
|
40188
|
+
else {
|
|
40189
|
+
removeClass(this.$el, 'is-empty');
|
|
40190
|
+
}
|
|
40191
|
+
},
|
|
40192
|
+
clearDragState: () => {
|
|
40193
|
+
var _a;
|
|
40194
|
+
DRAG_STATE_CLASSES.forEach(className => {
|
|
40195
|
+
removeClass(findAll(`.${className}`, this.$el), className);
|
|
40196
|
+
});
|
|
40197
|
+
if ((_a = this._dragging) === null || _a === void 0 ? void 0 : _a.preview) {
|
|
40198
|
+
this._dragging.preview.remove();
|
|
40199
|
+
}
|
|
40200
|
+
this._dragging = null;
|
|
40201
|
+
},
|
|
40202
|
+
dragStart: (e) => {
|
|
40203
|
+
if (this.$options.disabled || !this.$options.draggable) {
|
|
40204
|
+
return;
|
|
40205
|
+
}
|
|
40206
|
+
// 기존 드래그 상태 정리 (이전 드래그가 중단된 경우 대비)
|
|
40207
|
+
this._hidden.clearDragState();
|
|
40208
|
+
const value = attr(e.currentTarget, 'data-value');
|
|
40209
|
+
if (!value) {
|
|
40210
|
+
return;
|
|
40211
|
+
}
|
|
40212
|
+
const selected = this._hidden.getSelection().map((item) => item.value);
|
|
40213
|
+
const isGroup = selected.length > 1 && selected.includes(value);
|
|
40214
|
+
const dragValues = isGroup ? selected : [value];
|
|
40215
|
+
this._dragging = { values: dragValues, isGroup: isGroup, preview: null };
|
|
40216
|
+
if (e.dataTransfer) {
|
|
40217
|
+
e.dataTransfer.setData('text/plain', value);
|
|
40218
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
40219
|
+
if (isGroup) {
|
|
40220
|
+
const preview = document.createElement('div');
|
|
40221
|
+
preview.className = 'sortablelist-drag-preview';
|
|
40222
|
+
preview.setAttribute('data-count', String(dragValues.length));
|
|
40223
|
+
const list = document.createElement('div');
|
|
40224
|
+
list.className = 'sortablelist-drag-preview-list';
|
|
40225
|
+
dragValues.forEach((dragValue) => {
|
|
40226
|
+
const itemEl = find(`[data-value="${CSS.escape(dragValue)}"]`, this.$options.delegates.list);
|
|
40227
|
+
if (!(itemEl instanceof HTMLElement)) {
|
|
40228
|
+
return;
|
|
40229
|
+
}
|
|
40230
|
+
const clone = itemEl.cloneNode(true);
|
|
40231
|
+
removeClass(clone, CLASS_DRAGGING);
|
|
40232
|
+
removeClass(clone, CLASS_GROUP_DRAGGING);
|
|
40233
|
+
removeClass(clone, CLASS_DRAG_OVER_TOP);
|
|
40234
|
+
removeClass(clone, CLASS_DRAG_OVER_BOTTOM);
|
|
40235
|
+
addClass(clone, 'is-ghost');
|
|
40236
|
+
list.appendChild(clone);
|
|
40237
|
+
});
|
|
40238
|
+
preview.appendChild(list);
|
|
40239
|
+
document.body.appendChild(preview);
|
|
40240
|
+
e.dataTransfer.setDragImage(preview, this.DRAG_IMAGE_OFFSET_X, this.DRAG_IMAGE_OFFSET_Y);
|
|
40241
|
+
this._dragging.preview = preview;
|
|
40242
|
+
}
|
|
40243
|
+
}
|
|
40244
|
+
findAll('.dropdown-item', this.$options.delegates.list).forEach((node) => {
|
|
40245
|
+
const itemValue = attr(node, 'data-value');
|
|
40246
|
+
if (dragValues.includes(itemValue)) {
|
|
40247
|
+
addClass(node, CLASS_DRAGGING);
|
|
40248
|
+
if (isGroup) {
|
|
40249
|
+
addClass(node, CLASS_GROUP_DRAGGING);
|
|
40250
|
+
}
|
|
40251
|
+
}
|
|
40252
|
+
});
|
|
40253
|
+
},
|
|
40254
|
+
dragOver: (e) => {
|
|
40255
|
+
if (!this._dragging || this.$options.disabled || !this.$options.draggable) {
|
|
40256
|
+
return;
|
|
40257
|
+
}
|
|
40258
|
+
e.preventDefault();
|
|
40259
|
+
if (!(e.currentTarget instanceof HTMLElement)) {
|
|
40260
|
+
return;
|
|
40261
|
+
}
|
|
40262
|
+
const target = e.currentTarget;
|
|
40263
|
+
const value = attr(target, 'data-value');
|
|
40264
|
+
if (this._dragging.values.includes(value)) {
|
|
40265
|
+
return;
|
|
40266
|
+
}
|
|
40267
|
+
removeClass(target, CLASS_DRAG_OVER_TOP);
|
|
40268
|
+
removeClass(target, CLASS_DRAG_OVER_BOTTOM);
|
|
40269
|
+
const rect = target.getBoundingClientRect();
|
|
40270
|
+
const midpoint = rect.top + rect.height * this.DRAG_OVER_THRESHOLD_RATIO;
|
|
40271
|
+
if (e.clientY > midpoint) {
|
|
40272
|
+
addClass(target, CLASS_DRAG_OVER_BOTTOM);
|
|
40273
|
+
}
|
|
40274
|
+
else {
|
|
40275
|
+
addClass(target, CLASS_DRAG_OVER_TOP);
|
|
40276
|
+
}
|
|
40277
|
+
},
|
|
40278
|
+
dragLeave: (e) => {
|
|
40279
|
+
if (e.currentTarget instanceof HTMLElement) {
|
|
40280
|
+
removeClass(e.currentTarget, 'is-drag-over-top');
|
|
40281
|
+
removeClass(e.currentTarget, 'is-drag-over-bottom');
|
|
40282
|
+
}
|
|
40283
|
+
},
|
|
40284
|
+
drop: (e) => {
|
|
40285
|
+
if (!this._dragging || this.$options.disabled || !this.$options.draggable) {
|
|
40286
|
+
return;
|
|
40287
|
+
}
|
|
40288
|
+
e.preventDefault();
|
|
40289
|
+
if (!(e.currentTarget instanceof HTMLElement)) {
|
|
40290
|
+
return;
|
|
40291
|
+
}
|
|
40292
|
+
const targetEl = e.currentTarget;
|
|
40293
|
+
const targetValue = attr(targetEl, 'data-value');
|
|
40294
|
+
const dragValues = this._dragging.values;
|
|
40295
|
+
if (!targetValue || dragValues.includes(targetValue)) {
|
|
40296
|
+
this._hidden.clearDragState();
|
|
40297
|
+
return;
|
|
40298
|
+
}
|
|
40299
|
+
const items = this.$options.data;
|
|
40300
|
+
const dragItems = items.filter((item) => dragValues.includes(item.value));
|
|
40301
|
+
const remain = items.filter((item) => !dragValues.includes(item.value));
|
|
40302
|
+
const targetIndex = remain.findIndex((item) => item.value === targetValue);
|
|
40303
|
+
const rect = targetEl.getBoundingClientRect();
|
|
40304
|
+
const midpoint = rect.top + rect.height * this.DRAG_OVER_THRESHOLD_RATIO;
|
|
40305
|
+
const insertAfter = e.clientY > midpoint;
|
|
40306
|
+
const insertIndex = targetIndex === -1 ? remain.length : insertAfter ? targetIndex + 1 : targetIndex;
|
|
40307
|
+
remain.splice(insertIndex, 0, ...dragItems);
|
|
40308
|
+
this.$options.data = remain;
|
|
40309
|
+
this._hidden.reRender();
|
|
40310
|
+
this._hidden.updateControls();
|
|
40311
|
+
this.$event(this, 'onChange', this.$options.data);
|
|
40312
|
+
this._hidden.clearDragState();
|
|
40313
|
+
},
|
|
40314
|
+
dragEnd: () => {
|
|
40315
|
+
this._hidden.clearDragState();
|
|
40316
|
+
},
|
|
40317
|
+
setData: (data) => {
|
|
40318
|
+
// 드래그 중일 경우 상태 정리 (DOM 요소가 제거되면 dragend 이벤트가 발생하지 않을 수 있음)
|
|
40319
|
+
this._hidden.clearDragState();
|
|
40320
|
+
this._hidden.validateData(data);
|
|
40321
|
+
this.$options.data = data;
|
|
40322
|
+
this._hidden.hydrateSelection(data);
|
|
40323
|
+
this._hidden.syncSelection();
|
|
40324
|
+
this._hidden.reRender();
|
|
40325
|
+
this._hidden.updateControls();
|
|
40326
|
+
this.$event(this, 'onChange', this.$options.data);
|
|
40327
|
+
},
|
|
40328
|
+
disable: () => {
|
|
40329
|
+
// 드래그 중일 경우 상태 정리
|
|
40330
|
+
this._hidden.clearDragState();
|
|
40331
|
+
this.$options.disabled = true;
|
|
40332
|
+
addClass(this.$el, 'is-disabled');
|
|
40333
|
+
this._hidden.reRender();
|
|
40334
|
+
this._hidden.updateControls();
|
|
40335
|
+
},
|
|
40336
|
+
enable: () => {
|
|
40337
|
+
// 드래그 중일 경우 상태 정리
|
|
40338
|
+
this._hidden.clearDragState();
|
|
40339
|
+
this.$options.disabled = false;
|
|
40340
|
+
removeClass(this.$el, 'is-disabled');
|
|
40341
|
+
this._hidden.reRender();
|
|
40342
|
+
this._hidden.updateControls();
|
|
40343
|
+
}
|
|
40344
|
+
};
|
|
40345
|
+
this.config = {
|
|
40346
|
+
name: this.$selector.name || this._uid,
|
|
40347
|
+
data: [],
|
|
40348
|
+
delegates: {
|
|
40349
|
+
list: '.sortablelist-items'
|
|
40350
|
+
},
|
|
40351
|
+
buttonPosition: 'left',
|
|
40352
|
+
draggable: false,
|
|
40353
|
+
textSets: {
|
|
40354
|
+
noData: DEFAULT_NO_DATA
|
|
40355
|
+
},
|
|
40356
|
+
height: 150
|
|
40357
|
+
};
|
|
40358
|
+
this.events = {
|
|
40359
|
+
onChange: true
|
|
40360
|
+
};
|
|
40361
|
+
this.methods = {
|
|
40362
|
+
getData() {
|
|
40363
|
+
return this.$options.data;
|
|
40364
|
+
},
|
|
40365
|
+
setData(data) {
|
|
40366
|
+
const next = isArray$1(data) ? data : data && 'data' in data ? data.data : null;
|
|
40367
|
+
if (!isArray$1(next)) {
|
|
40368
|
+
throw new TypeError('Invalid SortableList data: data must be an array');
|
|
40369
|
+
}
|
|
40370
|
+
this._hidden.setData(next);
|
|
40371
|
+
},
|
|
40372
|
+
disable() {
|
|
40373
|
+
this._hidden.disable();
|
|
40374
|
+
},
|
|
40375
|
+
enable() {
|
|
40376
|
+
this._hidden.enable();
|
|
40377
|
+
}
|
|
40378
|
+
};
|
|
40379
|
+
this.$selector = this.$selector;
|
|
40380
|
+
this.$init(this, options);
|
|
40381
|
+
}
|
|
40382
|
+
template(config) {
|
|
40383
|
+
const styles = {};
|
|
40384
|
+
if (config.width) {
|
|
40385
|
+
styles.width = getUnit('width', config.width);
|
|
40386
|
+
}
|
|
40387
|
+
const listStyles = {};
|
|
40388
|
+
if (config.height) {
|
|
40389
|
+
const heightValue = getUnit('height', config.height);
|
|
40390
|
+
styles.height = heightValue;
|
|
40391
|
+
listStyles.height = heightValue;
|
|
40392
|
+
listStyles.maxHeight = heightValue;
|
|
40393
|
+
}
|
|
40394
|
+
const controlClass = 'sortablelist-controls gn-control is-small has-arrange is-vertical is-center' + (config.buttonPosition === 'right' ? ' is-right' : '');
|
|
40395
|
+
const buttonDisabled = config.disabled || (config.data || []).length === 0;
|
|
40396
|
+
return (createElement$1("div", { id: this._uid, className: 'gn-sortablelist' + (config.disabled ? ' is-disabled' : ''), style: styles },
|
|
40397
|
+
createElement$1("div", { className: controlClass },
|
|
40398
|
+
createElement$1("button", { type: "button", className: "gn-button is-outline", "on-click": this._hidden.sort.bind(this, 'up-all'), disabled: buttonDisabled },
|
|
40399
|
+
createElement$1("span", { className: "gn-icon" },
|
|
40400
|
+
createElement$1("i", { className: "fa fa-light fa-angle-double-up" }))),
|
|
40401
|
+
createElement$1("button", { type: "button", className: "gn-button is-outline", "on-click": this._hidden.sort.bind(this, 'up'), disabled: buttonDisabled },
|
|
40402
|
+
createElement$1("span", { className: "gn-icon" },
|
|
40403
|
+
createElement$1("i", { className: "fa fa-light fa-angle-up" }))),
|
|
40404
|
+
createElement$1("button", { type: "button", className: "gn-button is-outline", "on-click": this._hidden.sort.bind(this, 'down'), disabled: buttonDisabled },
|
|
40405
|
+
createElement$1("span", { className: "gn-icon" },
|
|
40406
|
+
createElement$1("i", { className: "fa fa-light fa-angle-down" }))),
|
|
40407
|
+
createElement$1("button", { type: "button", className: "gn-button is-outline", "on-click": this._hidden.sort.bind(this, 'down-all'), disabled: buttonDisabled },
|
|
40408
|
+
createElement$1("span", { className: "gn-icon" },
|
|
40409
|
+
createElement$1("i", { className: "fa fa-light fa-angle-double-down" })))),
|
|
40410
|
+
createElement$1("div", { className: "gn-dropdown is-opened sortablelist-items" },
|
|
40411
|
+
createElement$1("div", { className: "dropdown-items", style: listStyles }, this._hidden.renderSub()))));
|
|
40412
|
+
}
|
|
40413
|
+
beforeMount() {
|
|
40414
|
+
this._hidden.validateData(this.$options.data);
|
|
40415
|
+
this._hidden.hydrateSelection(this.$options.data);
|
|
40416
|
+
}
|
|
40417
|
+
completed() {
|
|
40418
|
+
this._hidden.updateControls();
|
|
40419
|
+
}
|
|
40420
|
+
destroyed() {
|
|
40421
|
+
this._hidden.clearDragState();
|
|
40422
|
+
}
|
|
40423
|
+
}
|
|
40424
|
+
|
|
39765
40425
|
class Splitter extends GNCoreInstance {
|
|
39766
40426
|
constructor(name, selector, options = {}) {
|
|
39767
40427
|
super(name, selector, options);
|
|
@@ -40409,6 +41069,7 @@
|
|
|
40409
41069
|
picklist: Picklist,
|
|
40410
41070
|
progressbar: Progressbar,
|
|
40411
41071
|
selectbutton: SelectButton,
|
|
41072
|
+
sortablelist: SortableList,
|
|
40412
41073
|
splitter: Splitter,
|
|
40413
41074
|
switch: Switch,
|
|
40414
41075
|
syntaxinput: SyntaxInput,
|