fix: tooltip issue about customer follower
change: Grid.export optimized (compression with `deflate`) feature: ui-tab feature: Popup.closable
This commit is contained in:
parent
f54eb3ac24
commit
e07342a257
@ -360,7 +360,7 @@ export default class CustomerCommunication {
|
||||
);
|
||||
this._var.followers.appendChild(item);
|
||||
if (span.scrollWidth > span.offsetWidth) {
|
||||
tips.splice(0, 0, r('P_WO_NAME_COLON', 'Name:') + ` ${c.Name}`);
|
||||
tips.splice(0, 0, r('P_WO_NAME_COLON', 'Name:') + ` ${f.Name}`);
|
||||
}
|
||||
setTooltip(span, tips.join('\n'));
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import { createElement } from "./functions";
|
||||
import { createIcon, changeIcon, resolveIcon } from "./ui/icon";
|
||||
import { createCheckbox, createRadiobox, resolveCheckbox } from "./ui/checkbox";
|
||||
import { setTooltip, resolveTooltip } from "./ui/tooltip";
|
||||
import { createTab } from "./ui/tab";
|
||||
import { Dropdown } from "./ui/dropdown";
|
||||
import { Grid } from "./ui/grid/grid";
|
||||
import { GridColumn, GridInputColumn, GridDropdownColumn, GridCheckboxColumn, GridIconColumn, GridTextColumn, GridDateColumn } from './ui/grid/column';
|
||||
@ -25,6 +26,8 @@ export {
|
||||
// tooltip
|
||||
setTooltip,
|
||||
resolveTooltip,
|
||||
// tab
|
||||
createTab,
|
||||
// dropdown
|
||||
Dropdown,
|
||||
// grid
|
||||
|
@ -70,6 +70,10 @@ $buttonHeight: 28px;
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
>.ui-popup-header-title.no-move {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
>.ui-popup-header-icons {
|
||||
flex: 0 0 auto;
|
||||
padding: 10px 12px 6px 0;
|
||||
|
47
lib/ui/css/tab.scss
Normal file
47
lib/ui/css/tab.scss
Normal file
@ -0,0 +1,47 @@
|
||||
.ui-tab-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
--header-line-height: 24px;
|
||||
--header-padding: 6px 6px 0;
|
||||
--header-hover-color: #b9b9b9;
|
||||
--header-selected-color: rgb(173, 84, 12);
|
||||
|
||||
>.ui-tab-header {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
line-height: var(--header-line-height);
|
||||
padding: var(--header-padding);
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
user-select: none;
|
||||
|
||||
>.ui-tab-title {
|
||||
border: 1px solid transparent;
|
||||
background-color: var(--bg-color);
|
||||
cursor: pointer;
|
||||
padding: 0 12px;
|
||||
|
||||
&:hover {
|
||||
color: var(--header-hover-color);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border-color: var(--border-color);
|
||||
border-bottom-color: var(--bg-color);
|
||||
color: var(--header-selected-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
>.ui-tab-page {
|
||||
flex: 1 1 auto;
|
||||
padding: 6px;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: none;
|
||||
}
|
||||
}
|
@ -16,6 +16,8 @@ import { GridColumn, GridInputColumn, GridTextColumn, GridDropdownColumn, GridCh
|
||||
* @version 1.0.2
|
||||
*/
|
||||
|
||||
const ScriptPath = (self.document == null ? self.location.href : self.document.currentScript.src).replace(/\?.+$/, '');
|
||||
|
||||
const ColumnChangedType = {
|
||||
Reorder: 'reorder',
|
||||
Resize: 'resize',
|
||||
@ -2092,7 +2094,7 @@ export class Grid {
|
||||
* }>
|
||||
* }
|
||||
* ```
|
||||
* @param {boolean} compressed - 是否压缩
|
||||
* @param {boolean} [compressed=true] - 是否采用 deflate 压缩
|
||||
* @returns {Promise<Uint8Array>} 返回 `Uint8Array` 数据对象
|
||||
* @since 1.0.2
|
||||
*/
|
||||
@ -2150,15 +2152,14 @@ export class Grid {
|
||||
sortKey: this.sortKey,
|
||||
sortArray: this.sortArray
|
||||
};
|
||||
const json = JSON.stringify(data);
|
||||
const uncompressed = json => new TextEncoder('utf-8').encode(json);
|
||||
if (compressed === false) {
|
||||
const encoder = new TextEncoder();
|
||||
const uncompressed = encoder.encode(JSON.stringify(data));
|
||||
return Promise.resolve(uncompressed);
|
||||
return Promise.resolve(uncompressed(json));
|
||||
}
|
||||
const js = new Blob(['function h(e,t,o){if(null==e)return"";let r;const l={},h={};let s="",n="",p="",a=2,f=3,c=2;const u=[];let i=0,d=0;for(let w=0;w<e.length;w+=1)if(s=e.charAt(w),Object.prototype.hasOwnProperty.call(l,s)||(l[s]=f++,h[s]=!0),n=p+s,Object.prototype.hasOwnProperty.call(l,n))p=n;else{if(Object.prototype.hasOwnProperty.call(h,p)){if(p.charCodeAt(0)<256){for(let e=0;e<c;e++)i<<=1,d==t-1?(d=0,u.push(o(i)),i=0):d++;r=p.charCodeAt(0);for(let e=0;e<8;e++)i=i<<1|1&r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r>>=1}else{r=1;for(let e=0;e<c;e++)i=i<<1|r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r=0;r=p.charCodeAt(0);for(let e=0;e<16;e++)i=i<<1|1&r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r>>=1}0==--a&&(a=Math.pow(2,c),c++),delete h[p]}else{r=l[p];for(let e=0;e<c;e++)i=i<<1|1&r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r>>=1}0==--a&&(a=Math.pow(2,c),c++),l[n]=f++,p=String(s)}if(""!==p){if(Object.prototype.hasOwnProperty.call(h,p)){if(p.charCodeAt(0)<256){for(let e=0;e<c;e++)i<<=1,d==t-1?(d=0,u.push(o(i)),i=0):d++;r=p.charCodeAt(0);for(let e=0;e<8;e++)i=i<<1|1&r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r>>=1}else{r=1;for(let e=0;e<c;e++)i=i<<1|r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r=0;r=p.charCodeAt(0);for(let e=0;e<16;e++)i=i<<1|1&r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r>>=1}0==--a&&(a=Math.pow(2,c),c++),delete h[p]}else{r=l[p];for(let e=0;e<c;e++)i=i<<1|1&r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r>>=1}0==--a&&(a=Math.pow(2,c),c++)}r=2;for(let e=0;e<c;e++)i=i<<1|1&r,d==t-1?(d=0,u.push(o(i)),i=0):d++,r>>=1;let w=!0;do{i<<=1,d==t-1?(u.push(o(i)),w=!1):d++}while(w);return u.join("")}function s(e){return null==e?"":h(e,16,e=>String.fromCharCode(e))}function i(e){const t=s(e),o=new Uint8Array(2*t.length);for(let e=0,r=t.length;e<r;e++){const r=t.charCodeAt(e);o[2*e]=r>>>8,o[2*e+1]=r%256}return o}self.addEventListener("message",function(e){this.self.postMessage(i(e.data))},!1);']);
|
||||
return new Promise((resolve, reject) => {
|
||||
return new Promise(resolve => {
|
||||
let working;
|
||||
const url = URL.createObjectURL(js);
|
||||
const url = URL.createObjectURL(new Blob([`let wasm,WASM_VECTOR_LEN=0,encoder=new TextEncoder("utf-8"),cachegetUint8Memory0=null;function getUint8Memory0(){return null!==cachegetUint8Memory0&&cachegetUint8Memory0.buffer===wasm.memory.buffer||(cachegetUint8Memory0=new Uint8Array(wasm.memory.buffer)),cachegetUint8Memory0}let cachegetInt32Memory0=null;function getInt32Memory0(){return null!==cachegetInt32Memory0&&cachegetInt32Memory0.buffer===wasm.memory.buffer||(cachegetInt32Memory0=new Int32Array(wasm.memory.buffer)),cachegetInt32Memory0}function passArray8ToWasm0(e,t){const n=t(1*e.length);return getUint8Memory0().set(e,n/1),WASM_VECTOR_LEN=e.length,n}function getArrayU8FromWasm0(e,t){return getUint8Memory0().subarray(e/1,e/1+t)}function deflate_encode_raw(e){var t=passArray8ToWasm0(e,wasm.__wbindgen_malloc),n=WASM_VECTOR_LEN;wasm.deflate_encode_raw(8,t,n);var r=getInt32Memory0()[2],a=getInt32Memory0()[3],s=getArrayU8FromWasm0(r,a).slice();return wasm.__wbindgen_free(r,1*a),s}self.addEventListener("message",e=>{const t=e.data.type;if("init"===t)if("function"==typeof WebAssembly.instantiateStreaming){const t={},n=fetch(e.data.module);WebAssembly.instantiateStreaming(n,t).then(({instance:e})=>{wasm=e.exports,self.postMessage({type:"init",result:0})}).catch(e=>n.then(t=>{"application/wasm"!==t.headers.get("Content-Type")?self.postMessage({type:"init",error:"\`WebAssembly.instantiateStreaming\` failed because your server does not serve wasm with \`application/wasm\` MIME type. Original error: "+e.message}):self.postMessage({type:"init",error:e.message})}))}else self.postMessage({type:"init",error:"no \`WebAssembly.instantiateStreaming\`"});else if("compress"===t)if(null==wasm)self.postMessage({error:"no \`wasm\` instance"});else{let t=deflate_encode_raw(encoder.encode(e.data.text));self.postMessage(t,[t.buffer])}});`]));
|
||||
const worker = new Worker(url);
|
||||
/**
|
||||
* @private
|
||||
@ -2171,26 +2172,37 @@ export class Grid {
|
||||
URL.revokeObjectURL(url);
|
||||
next(data);
|
||||
}
|
||||
// 超过 60 秒则拒绝
|
||||
// 超过 30 秒则返回无压缩数据
|
||||
const timer = setTimeout(() => {
|
||||
if (working) {
|
||||
terminate(reject, { message: 'timeout' });
|
||||
// terminate(reject, { message: 'timeout' });
|
||||
terminate(resolve, { data: uncompressed(json), error: 'timeout' });
|
||||
}
|
||||
}, 60000);
|
||||
}, 30000);
|
||||
worker.addEventListener('message', e => {
|
||||
if (working) {
|
||||
clearTimeout(timer);
|
||||
terminate(resolve, e.data);
|
||||
if (e.data.error != null) {
|
||||
// terminate(reject, { message: e.data.error });
|
||||
terminate(resolve, { data: uncompressed(json), error: e.data.error });
|
||||
} else {
|
||||
if (e.data.type === 'init') {
|
||||
worker.postMessage({ type: 'compress', text: json });
|
||||
} else {
|
||||
clearTimeout(timer);
|
||||
terminate(resolve, { type: 'compressed', data: e.data });
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
worker.addEventListener('error', e => {
|
||||
if (working) {
|
||||
clearTimeout(timer);
|
||||
terminate(reject, e);
|
||||
// terminate(reject, e);
|
||||
terminate(resolve, { data: uncompressed(json), error: e.message });
|
||||
}
|
||||
})
|
||||
working = true;
|
||||
worker.postMessage(JSON.stringify(data));
|
||||
worker.postMessage({ type: 'init', module: ScriptPath.replace(/ui\.min\.js$/, 'wasm_flate_bg.wasm') });
|
||||
});
|
||||
}
|
||||
|
||||
|
2
lib/ui/popup.d.ts
vendored
2
lib/ui/popup.d.ts
vendored
@ -13,6 +13,8 @@ interface PopupOptions {
|
||||
zIndex?: number;
|
||||
/** 是否在获取焦点时修改 z-index */
|
||||
changeZIndex?: boolean;
|
||||
/** 是否允许关闭 */
|
||||
closable?: boolean;
|
||||
/** 是否允许移动 */
|
||||
movable?: boolean;
|
||||
/** 是否允许修改大小 */
|
||||
|
@ -172,7 +172,11 @@ export class Popup {
|
||||
let title = option.title;
|
||||
if (!(title instanceof HTMLElement)) {
|
||||
title = createElement('div', t => {
|
||||
t.className = 'ui-popup-header-title';
|
||||
if (option.movable === false) {
|
||||
t.className = 'ui-popup-header-title no-move';
|
||||
} else {
|
||||
t.className = 'ui-popup-header-title';
|
||||
}
|
||||
t.innerText = title;
|
||||
});
|
||||
}
|
||||
@ -244,15 +248,17 @@ export class Popup {
|
||||
});
|
||||
icons.appendChild(collapse);
|
||||
}
|
||||
const cancel = createIcon('fa-regular', 'times');
|
||||
cancel.tabIndex = tabIndex + 3;
|
||||
cancel.addEventListener('keypress', e => {
|
||||
if (e.key === ' ' || e.key === 'Enter') {
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
cancel.addEventListener('click', () => this.close());
|
||||
icons.appendChild(cancel);
|
||||
if (option.closable !== false) {
|
||||
const cancel = createIcon('fa-regular', 'times');
|
||||
cancel.tabIndex = tabIndex + 3;
|
||||
cancel.addEventListener('keypress', e => {
|
||||
if (e.key === ' ' || e.key === 'Enter') {
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
cancel.addEventListener('click', () => this.close());
|
||||
icons.appendChild(cancel);
|
||||
}
|
||||
});
|
||||
header.appendChild(icons);
|
||||
}),
|
||||
|
43
lib/ui/tab.js
Normal file
43
lib/ui/tab.js
Normal file
@ -0,0 +1,43 @@
|
||||
import "./css/tab.scss";
|
||||
|
||||
/**
|
||||
* Tab 页创建参数类
|
||||
* @typedef TabOption
|
||||
* @property {HTMLElement} container - 父容器
|
||||
*/
|
||||
|
||||
import { createElement } from "../functions";
|
||||
|
||||
/**
|
||||
* 创建 Tab 页
|
||||
* @param {TabOption | HTMLElement} options - 创建选项
|
||||
*/
|
||||
export function createTab(options) {
|
||||
if (options instanceof HTMLElement) {
|
||||
options = { container: options };
|
||||
}
|
||||
let container;
|
||||
if (options?.container instanceof HTMLElement) {
|
||||
container = options.container;
|
||||
if (!container.classList.contains('ui-tab-container')) {
|
||||
container.classList.add('ui-tab-container');
|
||||
}
|
||||
} else {
|
||||
container = createElement('div', 'ui-tab-container');
|
||||
}
|
||||
container.replaceChildren(
|
||||
createElement('div', header => {
|
||||
header.className = 'ui-tab-header';
|
||||
header.addEventListener('click', e => {
|
||||
const title = e.target;
|
||||
if (title.classList.contains('ui-tab-title')) {
|
||||
// title
|
||||
header.querySelectorAll('.ui-tab-title').forEach(t => t === title ? t.classList.add('selected') : t.classList.remove('selected'));
|
||||
// pages
|
||||
const page = title.dataset.for;
|
||||
container.querySelectorAll('[data-page]').forEach(p => p.style.display = p.dataset.page === page ? 'block' : '');
|
||||
}
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
34
package-lock.json
generated
34
package-lock.json
generated
@ -14,7 +14,7 @@
|
||||
"jsdoc": "^4.0.2",
|
||||
"postcss-preset-env": "^9.5.0",
|
||||
"sass": "^1.71.1",
|
||||
"typedoc": "^0.25.11",
|
||||
"typedoc": "^0.25.12",
|
||||
"vite": "^5.1.5",
|
||||
"vite-plugin-externals": "^0.6.2"
|
||||
}
|
||||
@ -1823,9 +1823,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001594",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001594.tgz",
|
||||
"integrity": "sha512-VblSX6nYqyJVs8DKFMldE2IVCJjZ225LW00ydtUWwh5hk9IfkTOffO6r8gJNsH0qqqeAF8KrbMYA2VEwTlGW5g==",
|
||||
"version": "1.0.30001597",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001597.tgz",
|
||||
"integrity": "sha512-7LjJvmQU6Sj7bL0j5b5WY/3n7utXUJvAe1lxhsHDbLmwX9mdL86Yjtr+5SRCyf8qME4M7pU2hswj0FpyBVCv9w==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -1991,9 +1991,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/cssdb": {
|
||||
"version": "7.11.1",
|
||||
"resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.1.tgz",
|
||||
"integrity": "sha512-F0nEoX/Rv8ENTHsjMPGHd9opdjGfXkgRBafSUGnQKPzGZFB7Lm0BbT10x21TMOCrKLbVsJ0NoCDMk6AfKqw8/A==",
|
||||
"version": "7.11.2",
|
||||
"resolved": "https://registry.npmjs.org/cssdb/-/cssdb-7.11.2.tgz",
|
||||
"integrity": "sha512-lhQ32TFkc1X4eTefGfYPvgovRSzIMofHkigfH8nWtyRL4XJLsRhJFreRvEgKzept7x1rjBuy3J/MurXLaFxW/A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@ -2038,9 +2038,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.694",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.694.tgz",
|
||||
"integrity": "sha512-kM3SwvGTYpBFJSc8jm4IYVMIOzDmAGd/Ry96O9elRiM6iEwHKNKhtXyFGzpfMMIGZD84W4/hyaULlMmNVvLQlQ==",
|
||||
"version": "1.4.699",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.699.tgz",
|
||||
"integrity": "sha512-I7q3BbQi6e4tJJN5CRcyvxhK0iJb34TV8eJQcgh+fR2fQ8miMgZcEInckCo1U9exDHbfz7DLDnFn8oqH/VcRKw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/entities": {
|
||||
@ -3463,9 +3463,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/typedoc": {
|
||||
"version": "0.25.11",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.11.tgz",
|
||||
"integrity": "sha512-5MbI1W/FOG6oXsd8bdssQidSTeKh8Kt3xA5uKVzI+K99uzP8EGN45uPnPvQesyaWdD+89s4wCQdtWEd8QUbiRg==",
|
||||
"version": "0.25.12",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.12.tgz",
|
||||
"integrity": "sha512-F+qhkK2VoTweDXd1c42GS/By2DvI2uDF4/EpG424dTexSHdtCH52C6IcAvMA6jR3DzAWZjHpUOW+E02kyPNUNw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lunr": "^2.3.9",
|
||||
@ -3480,13 +3480,13 @@
|
||||
"node": ">= 16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x"
|
||||
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
|
||||
"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
|
||||
"version": "5.4.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz",
|
||||
"integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==",
|
||||
"dev": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
|
@ -34,7 +34,7 @@
|
||||
"jsdoc": "^4.0.2",
|
||||
"postcss-preset-env": "^9.5.0",
|
||||
"sass": "^1.71.1",
|
||||
"typedoc": "^0.25.11",
|
||||
"typedoc": "^0.25.12",
|
||||
"vite": "^5.1.5",
|
||||
"vite-plugin-externals": "^0.6.2"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user