@nocobase/plugin-ai 2.1.0-alpha.10 → 2.1.0-alpha.11
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/{server/ai-employees/built-in/data-modeling/prompt.d.ts → ai/ai-employees/cole.d.ts} +1 -3
- package/dist/{server/ai-employees/built-in/nocobase-assistant/prompt.js → ai/ai-employees/cole.js} +15 -7
- package/dist/{server/ai-employees/built-in/data-organizer/prompt.d.ts → ai/ai-employees/dara.d.ts} +1 -3
- package/dist/{server/ai-employees/built-in/data-visualization/prompt.js → ai/ai-employees/dara.js} +21 -13
- package/dist/{server/ai-employees/built-in/data-visualization/prompt.d.ts → ai/ai-employees/dex.d.ts} +1 -3
- package/dist/{server/ai-employees/built-in/data-organizer/prompt.js → ai/ai-employees/dex.js} +15 -7
- package/dist/ai/ai-employees/ellis.d.ts +10 -0
- package/dist/{server/ai-employees/built-in/email-assistant/prompt.js → ai/ai-employees/ellis.js} +19 -11
- package/dist/ai/ai-employees/lexi.d.ts +10 -0
- package/dist/{server/ai-employees/built-in/translator/prompt.js → ai/ai-employees/lexi.js} +15 -7
- package/dist/ai/ai-employees/vera.d.ts +10 -0
- package/dist/{server/ai-employees/built-in/research-analyst/prompt.js → ai/ai-employees/vera.js} +15 -7
- package/dist/ai/ai-employees/viz.d.ts +10 -0
- package/dist/{server/ai-employees/built-in/insights-analyst/prompt.js → ai/ai-employees/viz.js} +15 -7
- package/dist/ai/skills/document-search/SKILLS.md +69 -0
- package/dist/ai/tools/chartGenerator.js +14 -3
- package/dist/ai/tools/formFiller.js +13 -2
- package/dist/{server/ai-employees/built-in/ai-coding/prompt.d.ts → ai/tools/getSkill.d.ts} +1 -3
- package/dist/{server/ai-employees/built-in/data-modeling/index.js → ai/tools/getSkill.js} +39 -32
- package/dist/ai/tools/suggestions.js +13 -2
- package/dist/client/{a06081a2b06f1c14.js → 200ac94fc7f6e97b.js} +1 -1
- package/dist/client/27539a4356faebb1.js +10 -0
- package/dist/client/2db4faf814179140.js +10 -0
- package/dist/client/{521c94db45b1e031.js → 4f9117811ffc7ab3.js} +1 -1
- package/dist/client/{c49557cc10afc6b2.js → 5af11e24bcb39ac4.js} +1 -1
- package/dist/client/62bf6ed27c8de0df.js +10 -0
- package/dist/client/6dc8c9b641452067.js +10 -0
- package/dist/client/8169eb2b48edf6c7.js +10 -0
- package/dist/client/81f6436fd9322dc1.js +10 -0
- package/dist/client/{33811690df6f43ba.js → 85af3d6d85eb5b2b.js} +1 -1
- package/dist/client/87bc4d3cb55e4006.js +10 -0
- package/dist/client/9ac11803370a9625.js +10 -0
- package/dist/client/9c00efb8eb0b4d69.js +10 -0
- package/dist/client/{f74949b95f9bbb91.js → a4948d5b70172a69.js} +1 -1
- package/dist/client/ai-employees/admin/SkillSettings.d.ts +7 -5
- package/dist/{server/ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_accounts_en.d.ts → client/ai-employees/admin/ToolsSettings.d.ts} +8 -4
- package/dist/client/ai-employees/admin/mcp/MCPSettings.d.ts +10 -0
- package/dist/client/ai-employees/admin/mcp/MCPToolsList.d.ts +19 -0
- package/dist/client/ai-employees/admin/mcp/context.d.ts +15 -0
- package/dist/client/ai-employees/admin/mcp/schemas.d.ts +1286 -0
- package/dist/client/ai-employees/chatbox/utils.d.ts +3 -7
- package/dist/client/ai-employees/types.d.ts +5 -4
- package/dist/client/c83c2cae956ba914.js +10 -0
- package/dist/client/{6fcc98eb80deed47.js → d4e2ed9fa44a82b2.js} +1 -1
- package/dist/client/{5be6710cc905ec12.js → f944d487b7ff1f00.js} +1 -1
- package/dist/client/index.js +2 -2
- package/dist/client/repositories/AIConfigRepository.d.ts +8 -1
- package/dist/collections/ai-employees.js +2 -1
- package/dist/collections/ai-mcp-clients.d.ts +51 -0
- package/dist/collections/ai-mcp-clients.js +111 -0
- package/dist/externalVersion.js +14 -14
- package/dist/locale/en-US.json +65 -8
- package/dist/locale/zh-CN.json +66 -9
- package/dist/node_modules/fast-glob/package.json +1 -1
- package/dist/node_modules/flexsearch/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/package.json +1 -1
- package/dist/node_modules/openai/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/ai-employees/ai-employee.d.ts +5 -1
- package/dist/server/ai-employees/ai-employee.js +90 -13
- package/dist/server/ai-employees/middleware/index.d.ts +1 -0
- package/dist/server/ai-employees/middleware/index.js +2 -0
- package/dist/server/ai-employees/middleware/skill-tools.d.ts +12 -0
- package/dist/server/ai-employees/middleware/skill-tools.js +74 -0
- package/dist/server/ai-employees/prompts.d.ts +6 -1
- package/dist/server/ai-employees/prompts.js +9 -1
- package/dist/server/ai-employees/templates/form-assistant.d.ts +2 -2
- package/dist/server/ai-employees/templates/form-assistant.js +2 -2
- package/dist/server/ai-employees/utils.js +2 -2
- package/dist/server/{ai-employees/built-in/ai-coding/document/basic/flow-resource.d.ts → collections/ai-mcp-clients.d.ts} +1 -4
- package/dist/server/{ai-employees/built-in/ai-coding/prompt.js → collections/ai-mcp-clients.js} +12 -10
- package/dist/server/{ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_opportunities_en.d.ts → collections/ai-skills.d.ts} +1 -4
- package/dist/server/{migrations/20250923221107-setup-build-in.js → collections/ai-skills.js} +46 -13
- package/dist/server/manager/ai-coding-manager.d.ts +1 -2
- package/dist/server/manager/ai-coding-manager.js +0 -41
- package/dist/server/manager/built-in-manager.d.ts +2 -4
- package/dist/server/manager/built-in-manager.js +7 -118
- package/dist/server/migrations/20260306000001-migrate-skill-settings-tools.js +68 -0
- package/dist/server/plugin.d.ts +0 -1
- package/dist/server/plugin.js +17 -8
- package/dist/server/resource/aiEmployees.js +5 -7
- package/dist/server/{ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_contacts_en.d.ts → resource/aiMcpClients.d.ts} +3 -5
- package/dist/server/resource/aiMcpClients.js +78 -0
- package/dist/server/{ai-employees/built-in/ai-coding/document/example/js-column/index.d.ts → resource/aiSkills.d.ts} +3 -7
- package/dist/server/resource/aiSkills.js +71 -0
- package/dist/server/resource/aiTools.js +4 -6
- package/dist/server/tools/docs.js +2 -2
- package/dist/server/tools/workflow-caller.js +1 -0
- package/package.json +2 -2
- package/dist/client/16dbe01d9077bb74.js +0 -10
- package/dist/client/180c8b1051a4f36e.js +0 -10
- package/dist/client/41229e007006e7f6.js +0 -10
- package/dist/client/41950da4c64caf73.js +0 -10
- package/dist/client/585ba360c7c57caf.js +0 -10
- package/dist/client/9f62a4c5136dfe8b.js +0 -10
- package/dist/client/b7f721f8dabb54e5.js +0 -10
- package/dist/client/bc471dd60174458c.js +0 -10
- package/dist/client/c40ed1a900aefb67.js +0 -10
- package/dist/server/ai-employees/built-in/ai-coding/document/basic/flow-resource.js +0 -256
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-column/index.js +0 -48
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_accounts_en.js +0 -452
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_contacts_en.js +0 -363
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_opportunities_en.js +0 -270
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_quotations_en.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_quotations_en.js +0 -219
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_tickets_en.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-column/js_columns_for_tickets_en.js +0 -409
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/accounts_filter_ant_style.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/accounts_filter_ant_style.js +0 -324
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/contacts_filter_ant_style.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/contacts_filter_ant_style.js +0 -309
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/index.d.ts +0 -15
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/index.js +0 -50
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/leads_filter_ant_style.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/leads_filter_ant_style.js +0 -345
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/opportunities_filter_ant_style.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/opportunities_filter_ant_style.js +0 -381
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/product_categories_ant_style.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/product_categories_ant_style.js +0 -545
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/tickets_filter_ant_style.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/example/js-filter/tickets_filter_ant_style.js +0 -346
- package/dist/server/ai-employees/built-in/ai-coding/document/js-action.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/js-action.js +0 -102
- package/dist/server/ai-employees/built-in/ai-coding/document/js-block.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/js-block.js +0 -314
- package/dist/server/ai-employees/built-in/ai-coding/document/js-column.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/js-column.js +0 -113
- package/dist/server/ai-employees/built-in/ai-coding/document/js-field.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/js-field.js +0 -498
- package/dist/server/ai-employees/built-in/ai-coding/document/js-item.d.ts +0 -13
- package/dist/server/ai-employees/built-in/ai-coding/document/js-item.js +0 -184
- package/dist/server/ai-employees/built-in/ai-coding/index.d.ts +0 -37
- package/dist/server/ai-employees/built-in/ai-coding/index.js +0 -99
- package/dist/server/ai-employees/built-in/ai-coding/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/ai-coding/profile.js +0 -60
- package/dist/server/ai-employees/built-in/ai-coding/prompt_en.md +0 -110
- package/dist/server/ai-employees/built-in/data-modeling/index.d.ts +0 -37
- package/dist/server/ai-employees/built-in/data-modeling/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/data-modeling/profile.js +0 -60
- package/dist/server/ai-employees/built-in/data-modeling/prompt.js +0 -283
- package/dist/server/ai-employees/built-in/data-organizer/index.d.ts +0 -37
- package/dist/server/ai-employees/built-in/data-organizer/index.js +0 -63
- package/dist/server/ai-employees/built-in/data-organizer/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/data-organizer/profile.js +0 -60
- package/dist/server/ai-employees/built-in/data-visualization/index.d.ts +0 -37
- package/dist/server/ai-employees/built-in/data-visualization/index.js +0 -58
- package/dist/server/ai-employees/built-in/data-visualization/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/data-visualization/profile.js +0 -60
- package/dist/server/ai-employees/built-in/email-assistant/index.d.ts +0 -34
- package/dist/server/ai-employees/built-in/email-assistant/index.js +0 -50
- package/dist/server/ai-employees/built-in/email-assistant/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/email-assistant/profile.js +0 -60
- package/dist/server/ai-employees/built-in/email-assistant/prompt.d.ts +0 -12
- package/dist/server/ai-employees/built-in/insights-analyst/index.d.ts +0 -37
- package/dist/server/ai-employees/built-in/insights-analyst/index.js +0 -63
- package/dist/server/ai-employees/built-in/insights-analyst/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/insights-analyst/profile.js +0 -60
- package/dist/server/ai-employees/built-in/insights-analyst/prompt.d.ts +0 -12
- package/dist/server/ai-employees/built-in/nocobase-assistant/index.d.ts +0 -34
- package/dist/server/ai-employees/built-in/nocobase-assistant/index.js +0 -50
- package/dist/server/ai-employees/built-in/nocobase-assistant/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/nocobase-assistant/profile.js +0 -60
- package/dist/server/ai-employees/built-in/nocobase-assistant/prompt.d.ts +0 -12
- package/dist/server/ai-employees/built-in/research-analyst/index.d.ts +0 -37
- package/dist/server/ai-employees/built-in/research-analyst/index.js +0 -63
- package/dist/server/ai-employees/built-in/research-analyst/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/research-analyst/profile.js +0 -60
- package/dist/server/ai-employees/built-in/research-analyst/prompt.d.ts +0 -12
- package/dist/server/ai-employees/built-in/translator/index.d.ts +0 -37
- package/dist/server/ai-employees/built-in/translator/index.js +0 -67
- package/dist/server/ai-employees/built-in/translator/profile.d.ts +0 -27
- package/dist/server/ai-employees/built-in/translator/profile.js +0 -60
- package/dist/server/ai-employees/built-in/translator/prompt.d.ts +0 -12
- /package/dist/server/migrations/{20250923221107-setup-build-in.d.ts → 20260306000001-migrate-skill-settings-tools.d.ts} +0 -0
|
@@ -1,452 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* This file is part of the NocoBase (R) project.
|
|
3
|
-
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
-
* Authors: NocoBase Team.
|
|
5
|
-
*
|
|
6
|
-
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
-
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
var __defProp = Object.defineProperty;
|
|
11
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
-
var __export = (target, all) => {
|
|
15
|
-
for (var name in all)
|
|
16
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
-
};
|
|
18
|
-
var __copyProps = (to, from, except, desc) => {
|
|
19
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
-
for (let key of __getOwnPropNames(from))
|
|
21
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
-
}
|
|
24
|
-
return to;
|
|
25
|
-
};
|
|
26
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
-
var js_columns_for_accounts_en_exports = {};
|
|
28
|
-
__export(js_columns_for_accounts_en_exports, {
|
|
29
|
-
default: () => js_columns_for_accounts_en_default
|
|
30
|
-
});
|
|
31
|
-
module.exports = __toCommonJS(js_columns_for_accounts_en_exports);
|
|
32
|
-
var js_columns_for_accounts_en_default = {
|
|
33
|
-
name: "js_columns_for_accounts",
|
|
34
|
-
content: String.raw`# NocoBase JS Column Examples - Accounts Table
|
|
35
|
-
|
|
36
|
-
## Overview
|
|
37
|
-
Practical JavaScript column examples for the accounts table in CRM systems. These aggregated columns combine multiple fields, calculate derived metrics, and provide visual representations to enhance data readability and business insights.
|
|
38
|
-
|
|
39
|
-
## Selected JS Column Examples
|
|
40
|
-
|
|
41
|
-
## 1. Account Comprehensive Information Column
|
|
42
|
-
|
|
43
|
-
Displays core account information including name, number, type, and industry labels. Account name is clickable to open detail dialog.
|
|
44
|
-
|
|
45
|
-
\`\`\`javascript
|
|
46
|
-
// Account info card - Name, number, industry tags with clickable name
|
|
47
|
-
const name = ctx.record?.name || 'Unknown';
|
|
48
|
-
const accountNumber = ctx.record?.account_number || 'N/A';
|
|
49
|
-
const industry = ctx.record?.industry || '';
|
|
50
|
-
const type = ctx.record?.type || '';
|
|
51
|
-
const account_id = ctx.record?.id;
|
|
52
|
-
|
|
53
|
-
// Industry mapping and colors
|
|
54
|
-
const industryMap = {
|
|
55
|
-
'Technology': { label: 'Tech', color: '#1677ff' },
|
|
56
|
-
'Healthcare': { label: 'Health', color: '#52c41a' },
|
|
57
|
-
'Finance': { label: 'Finance', color: '#faad14' },
|
|
58
|
-
'Retail': { label: 'Retail', color: '#fa8c16' },
|
|
59
|
-
'Education': { label: 'Edu', color: '#2563eb' },
|
|
60
|
-
'Manufacturing': { label: 'Mfg', color: '#eb2f96' },
|
|
61
|
-
'Real estate': { label: 'Real Estate', color: '#fa541c' },
|
|
62
|
-
'Energy': { label: 'Energy', color: '#fadb14' },
|
|
63
|
-
'Government': { label: 'Gov', color: '#73d13d' }
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const typeMap = {
|
|
67
|
-
'Customer': 'Customer',
|
|
68
|
-
'Partner': 'Partner',
|
|
69
|
-
'Competitor': 'Competitor',
|
|
70
|
-
'Vendor': 'Vendor',
|
|
71
|
-
'Prospect': 'Prospect',
|
|
72
|
-
'Other': 'Other'
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const industryInfo = industryMap[industry] || { label: industry, color: '#8c8c8c' };
|
|
76
|
-
const typeLabel = typeMap[type] || type;
|
|
77
|
-
|
|
78
|
-
ctx.element.innerHTML = \`
|
|
79
|
-
<div style="display:flex;flex-direction:column;gap:4px;">
|
|
80
|
-
<div style="display:flex;align-items:center;gap:8px;">
|
|
81
|
-
<strong
|
|
82
|
-
class="account-name-link"
|
|
83
|
-
style="color:#000;font-size:14px;cursor:pointer;text-decoration:none;"
|
|
84
|
-
onmouseover="this.style.color='#1677ff';this.style.textDecoration='underline'"
|
|
85
|
-
onmouseout="this.style.color='#000';this.style.textDecoration='none'"
|
|
86
|
-
>\${name}</strong>
|
|
87
|
-
\${type ? \`<span style="padding:2px 6px;background:#f0f5ff;color:#1677ff;border-radius:2px;font-size:11px;">\${typeLabel}</span>\` : ''}
|
|
88
|
-
</div>
|
|
89
|
-
<div style="display:flex;align-items:center;gap:6px;">
|
|
90
|
-
<span style="color:#8c8c8c;font-size:12px;">\${accountNumber}</span>
|
|
91
|
-
\${industry ? \`<span style="padding:2px 6px;background:\${industryInfo.color}15;color:\${industryInfo.color};border-radius:2px;font-size:11px;">\${industryInfo.label}</span>\` : ''}
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
\`;
|
|
95
|
-
|
|
96
|
-
// Add click handler for account name
|
|
97
|
-
if (account_id) {
|
|
98
|
-
const nameLink = ctx.element.querySelector('.account-name-link');
|
|
99
|
-
if (nameLink && !nameLink._eventBound) {
|
|
100
|
-
nameLink._eventBound = true;
|
|
101
|
-
nameLink.addEventListener('click', async () => {
|
|
102
|
-
await ctx.openView('c91bba4e338', {
|
|
103
|
-
collectionName: 'accounts',
|
|
104
|
-
dataSourceKey: 'main',
|
|
105
|
-
filterByTk: account_id
|
|
106
|
-
}); // Account dialog UID
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
\`\`\`
|
|
111
|
-
|
|
112
|
-
## 2. Health Score Column
|
|
113
|
-
|
|
114
|
-
Calculates account health score based on multiple dimensions including owner assignment, contacts, opportunities, recent activities, and revenue data.
|
|
115
|
-
|
|
116
|
-
\`\`\`javascript
|
|
117
|
-
// Account health score - Based on multiple indicators
|
|
118
|
-
const hasOwner = ctx.record?.owner_id ? 20 : 0;
|
|
119
|
-
const hasContacts = ctx.record?.contacts?.length > 0 ? 20 : 0;
|
|
120
|
-
const hasOpportunities = ctx.record?.opportunities?.length > 0 ? 20 : 0;
|
|
121
|
-
const hasRecentActivity = ctx.record?.updatedAt &&
|
|
122
|
-
(new Date() - new Date(ctx.record.updatedAt)) < 30 * 24 * 60 * 60 * 1000 ? 20 : 0;
|
|
123
|
-
const hasRevenue = ctx.record?.annual_revenue > 0 ? 20 : 0;
|
|
124
|
-
|
|
125
|
-
const score = hasOwner + hasContacts + hasOpportunities + hasRecentActivity + hasRevenue;
|
|
126
|
-
const level = score >= 80 ? 'Excellent' : score >= 60 ? 'Good' : score >= 40 ? 'Fair' : 'Poor';
|
|
127
|
-
const color = score >= 80 ? '#52c41a' : score >= 60 ? '#1677ff' : score >= 40 ? '#faad14' : '#ff4d4f';
|
|
128
|
-
|
|
129
|
-
ctx.element.innerHTML = \`
|
|
130
|
-
<div style="display:flex;align-items:center;gap:8px;">
|
|
131
|
-
<div style="position:relative;width:120px;height:8px;background:#f0f0f0;border-radius:4px;overflow:hidden;">
|
|
132
|
-
<div style="position:absolute;left:0;top:0;height:100%;width:\${score}%;background:\${color};border-radius:4px;transition:width 0.3s;"></div>
|
|
133
|
-
</div>
|
|
134
|
-
<span style="font-size:12px;color:\${color};font-weight:600;">\${score}% \${level}</span>
|
|
135
|
-
</div>
|
|
136
|
-
\`;
|
|
137
|
-
\`\`\`
|
|
138
|
-
|
|
139
|
-
## 3. Business Scale Indicator
|
|
140
|
-
|
|
141
|
-
Shows company scale level and annual revenue with different visual elements for different sizes.
|
|
142
|
-
|
|
143
|
-
\`\`\`javascript
|
|
144
|
-
// Business scale - Employee count and annual revenue combination
|
|
145
|
-
const employees = ctx.record?.employees || '';
|
|
146
|
-
const revenue = ctx.record?.annual_revenue || 0;
|
|
147
|
-
|
|
148
|
-
const formatRevenue = (val) => {
|
|
149
|
-
if (val >= 1000000) return \`$\${(val/1000000).toFixed(1)}M\`;
|
|
150
|
-
if (val >= 1000) return \`$\${(val/1000).toFixed(0)}K\`;
|
|
151
|
-
return \`$\${val}\`;
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
const sizeMap = {
|
|
155
|
-
'1-49': { label: 'Small', icon: '●', color: '#1677ff' },
|
|
156
|
-
'50-199': { label: 'Medium', icon: '●●', color: '#faad14' },
|
|
157
|
-
'200-999': { label: 'Large', icon: '●●●', color: '#52c41a' },
|
|
158
|
-
'1000+': { label: 'Enterprise', icon: '●●●●', color: '#eb2f96' }
|
|
159
|
-
};
|
|
160
|
-
|
|
161
|
-
const size = sizeMap[employees] || { label: 'Unknown', icon: '○', color: '#8c8c8c' };
|
|
162
|
-
|
|
163
|
-
ctx.element.innerHTML = \`
|
|
164
|
-
<div style="display:flex;flex-direction:column;gap:4px;">
|
|
165
|
-
<div style="display:flex;align-items:center;gap:6px;">
|
|
166
|
-
<span style="color:\${size.color};font-size:10px;">\${size.icon}</span>
|
|
167
|
-
<span style="color:#000;font-size:13px;font-weight:500;">\${size.label}</span>
|
|
168
|
-
</div>
|
|
169
|
-
\${revenue > 0 ? \`
|
|
170
|
-
<div style="color:#52c41a;font-size:14px;font-weight:600;">
|
|
171
|
-
\${formatRevenue(revenue)}
|
|
172
|
-
</div>
|
|
173
|
-
\` : '<span style="color:#bfbfbf;font-size:12px;">No revenue data</span>'}
|
|
174
|
-
</div>
|
|
175
|
-
\`;
|
|
176
|
-
\`\`\`
|
|
177
|
-
|
|
178
|
-
## 4. Relationship Network Badges
|
|
179
|
-
|
|
180
|
-
Displays counts of related leads, contacts, and opportunities. Click to show list where titles are clickable to open detail dialogs.
|
|
181
|
-
|
|
182
|
-
\`\`\`javascript
|
|
183
|
-
// Relationship network badges - Using ctx.viewer.drawer, list items clickable
|
|
184
|
-
const leads = ctx.record?.leads || [];
|
|
185
|
-
const contacts = ctx.record?.contacts || [];
|
|
186
|
-
const opportunities = ctx.record?.opportunities || [];
|
|
187
|
-
|
|
188
|
-
const badges = [
|
|
189
|
-
{
|
|
190
|
-
label: 'Leads',
|
|
191
|
-
type: 'leads',
|
|
192
|
-
count: leads.length,
|
|
193
|
-
color: '#722ed1',
|
|
194
|
-
icon: '👤',
|
|
195
|
-
items: leads,
|
|
196
|
-
dialogUID: 'c4f1bf0165c' // Contact dialog UID
|
|
197
|
-
},
|
|
198
|
-
{
|
|
199
|
-
label: 'Contacts',
|
|
200
|
-
type: 'contacts',
|
|
201
|
-
count: contacts.length,
|
|
202
|
-
color: '#1677ff',
|
|
203
|
-
icon: '📇',
|
|
204
|
-
items: contacts,
|
|
205
|
-
dialogUID: 'c4f1bf0165c' // Contact dialog UID
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
label: 'Opportunities',
|
|
209
|
-
type: 'opportunities',
|
|
210
|
-
count: opportunities.length,
|
|
211
|
-
color: '#52c41a',
|
|
212
|
-
icon: '💼',
|
|
213
|
-
items: opportunities,
|
|
214
|
-
dialogUID: '44be52bf4bb' // Opportunity dialog UID
|
|
215
|
-
}
|
|
216
|
-
].filter(b => b.count > 0);
|
|
217
|
-
|
|
218
|
-
ctx.element.innerHTML = \`
|
|
219
|
-
<div style="display:flex;gap:8px;flex-wrap:wrap;">
|
|
220
|
-
\${badges.length > 0 ? badges.map((badge, index) => \`
|
|
221
|
-
<a
|
|
222
|
-
href="javascript:void(0)"
|
|
223
|
-
class="badge-link"
|
|
224
|
-
data-index="\${index}"
|
|
225
|
-
style="
|
|
226
|
-
display:inline-flex;
|
|
227
|
-
align-items:center;
|
|
228
|
-
gap:4px;
|
|
229
|
-
padding:4px 8px;
|
|
230
|
-
background:\${badge.color}15;
|
|
231
|
-
border-radius:12px;
|
|
232
|
-
text-decoration:none;
|
|
233
|
-
transition:all 0.2s;
|
|
234
|
-
border:1px solid \${badge.color}30;
|
|
235
|
-
cursor:pointer;
|
|
236
|
-
"
|
|
237
|
-
onmouseover="this.style.background='\${badge.color}25';this.style.transform='scale(1.05)'"
|
|
238
|
-
onmouseout="this.style.background='\${badge.color}15';this.style.transform='scale(1)'"
|
|
239
|
-
>
|
|
240
|
-
<span style="font-size:12px;">\${badge.icon}</span>
|
|
241
|
-
<span style="color:\${badge.color};font-size:12px;font-weight:600;">\${badge.count}</span>
|
|
242
|
-
<span style="color:#595959;font-size:11px;">\${badge.label}</span>
|
|
243
|
-
</a>
|
|
244
|
-
\`).join('') : '<span style="color:#bfbfbf;font-size:12px;">No related data</span>'}
|
|
245
|
-
</div>
|
|
246
|
-
\`;
|
|
247
|
-
|
|
248
|
-
// Bind click events
|
|
249
|
-
ctx.element.querySelectorAll('.badge-link').forEach((link) => {
|
|
250
|
-
const badgeIndex = parseInt(link.dataset.index);
|
|
251
|
-
const badge = badges[badgeIndex];
|
|
252
|
-
|
|
253
|
-
link.addEventListener('click', (e) => {
|
|
254
|
-
e.preventDefault();
|
|
255
|
-
|
|
256
|
-
// Prepare detail content
|
|
257
|
-
let detailContent = '';
|
|
258
|
-
const formatValue = (val) => {
|
|
259
|
-
if (val >= 1000000) return \`$\${(val/1000000).toFixed(1)}M\`;
|
|
260
|
-
if (val >= 1000) return \`$\${(val/1000).toFixed(0)}K\`;
|
|
261
|
-
return \`$\${val}\`;
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
if (badge.type === 'opportunities') {
|
|
265
|
-
const totalValue = badge.items.reduce((sum, opp) => sum + (opp.amount || 0), 0);
|
|
266
|
-
|
|
267
|
-
detailContent = \`
|
|
268
|
-
<div style="padding:16px;">
|
|
269
|
-
<h4 style="margin:0 0 12px;color:#333;">Opportunities List</h4>
|
|
270
|
-
<div style="padding:8px;background:#e6f7ff;border-radius:4px;margin-bottom:12px;">
|
|
271
|
-
<strong>Total Pipeline Value: <span style="color:#52c41a;">\${formatValue(totalValue)}</span></strong>
|
|
272
|
-
</div>
|
|
273
|
-
<div style="max-height:400px;overflow-y:auto;">
|
|
274
|
-
\${badge.items.slice(0, 10).map(opp => \`
|
|
275
|
-
<div style="padding:8px;margin-bottom:8px;background:#f5f5f5;border-radius:4px;">
|
|
276
|
-
<div
|
|
277
|
-
class="item-title"
|
|
278
|
-
style="font-weight:500;margin-bottom:4px;color:#1677ff;cursor:pointer;"
|
|
279
|
-
onmouseover="this.style.textDecoration='underline'"
|
|
280
|
-
onmouseout="this.style.textDecoration='none'"
|
|
281
|
-
data-dialog="\${badge.dialogUID}"
|
|
282
|
-
>\${opp.name || 'Unnamed Opportunity'}</div>
|
|
283
|
-
<div style="font-size:12px;color:#8c8c8c;">
|
|
284
|
-
Amount: <strong style="color:#52c41a;">\${formatValue(opp.amount || 0)}</strong> |
|
|
285
|
-
Stage: \${opp.stage || 'Unknown'}
|
|
286
|
-
</div>
|
|
287
|
-
</div>
|
|
288
|
-
\`).join('')}
|
|
289
|
-
\${badge.items.length > 10 ? \`
|
|
290
|
-
<div style="padding:8px;text-align:center;color:#8c8c8c;font-size:12px;">
|
|
291
|
-
...and \${badge.items.length - 10} more opportunities
|
|
292
|
-
</div>
|
|
293
|
-
\` : ''}
|
|
294
|
-
</div>
|
|
295
|
-
</div>
|
|
296
|
-
\`;
|
|
297
|
-
} else {
|
|
298
|
-
// Similar implementation for leads and contacts
|
|
299
|
-
detailContent = \`
|
|
300
|
-
<div style="padding:16px;">
|
|
301
|
-
<h4 style="margin:0 0 12px;color:#333;">\${badge.label} List</h4>
|
|
302
|
-
<div style="max-height:400px;overflow-y:auto;">
|
|
303
|
-
\${badge.items.slice(0, 10).map(item => \`
|
|
304
|
-
<div style="padding:8px;margin-bottom:8px;background:#f5f5f5;border-radius:4px;">
|
|
305
|
-
<div
|
|
306
|
-
class="item-title"
|
|
307
|
-
style="font-weight:500;margin-bottom:4px;color:#1677ff;cursor:pointer;"
|
|
308
|
-
>\${item.name || 'Unnamed'}</div>
|
|
309
|
-
<div style="font-size:12px;color:#8c8c8c;">
|
|
310
|
-
\${item.email || 'No email'} | \${item.phone || 'No phone'}
|
|
311
|
-
</div>
|
|
312
|
-
</div>
|
|
313
|
-
\`).join('')}
|
|
314
|
-
</div>
|
|
315
|
-
</div>
|
|
316
|
-
\`;
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
// Use ctx.viewer.drawer to show content
|
|
320
|
-
const drawer = ctx.viewer.drawer({
|
|
321
|
-
title: \`\${badge.icon} \${badge.label} (\${badge.count})\`,
|
|
322
|
-
content: detailContent,
|
|
323
|
-
width: 500
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
});
|
|
327
|
-
\`\`\`
|
|
328
|
-
|
|
329
|
-
## 5. Activity Status Indicator
|
|
330
|
-
|
|
331
|
-
Shows account activity status based on last update time with visual indicators.
|
|
332
|
-
|
|
333
|
-
\`\`\`javascript
|
|
334
|
-
// Activity indicator - Based on last update time
|
|
335
|
-
const updatedAt = ctx.record?.updatedAt;
|
|
336
|
-
const createdAt = ctx.record?.createdAt;
|
|
337
|
-
|
|
338
|
-
const getTimeDiff = (date) => {
|
|
339
|
-
const diff = new Date() - new Date(date);
|
|
340
|
-
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
|
|
341
|
-
const hours = Math.floor(diff / (1000 * 60 * 60));
|
|
342
|
-
const minutes = Math.floor(diff / (1000 * 60));
|
|
343
|
-
|
|
344
|
-
if (days > 30) return { text: \`\${Math.floor(days/30)} months ago\`, status: 'inactive' };
|
|
345
|
-
if (days > 0) return { text: \`\${days} days ago\`, status: days > 7 ? 'warning' : 'active' };
|
|
346
|
-
if (hours > 0) return { text: \`\${hours} hours ago\`, status: 'active' };
|
|
347
|
-
return { text: \`\${minutes} minutes ago\`, status: 'active' };
|
|
348
|
-
};
|
|
349
|
-
|
|
350
|
-
const timeInfo = updatedAt ? getTimeDiff(updatedAt) : null;
|
|
351
|
-
const statusColors = {
|
|
352
|
-
active: '#52c41a',
|
|
353
|
-
warning: '#faad14',
|
|
354
|
-
inactive: '#ff4d4f'
|
|
355
|
-
};
|
|
356
|
-
|
|
357
|
-
ctx.element.innerHTML = timeInfo ? \`
|
|
358
|
-
<div style="display:flex;align-items:center;gap:6px;">
|
|
359
|
-
<div style="width:8px;height:8px;border-radius:50%;background:\${statusColors[timeInfo.status]};
|
|
360
|
-
\${timeInfo.status === 'active' ? 'animation: pulse 2s infinite;' : ''}"></div>
|
|
361
|
-
<span style="color:#595959;font-size:12px;">Updated \${timeInfo.text}</span>
|
|
362
|
-
</div>
|
|
363
|
-
<style>
|
|
364
|
-
@keyframes pulse {
|
|
365
|
-
0% { opacity: 1; }
|
|
366
|
-
50% { opacity: 0.5; }
|
|
367
|
-
100% { opacity: 1; }
|
|
368
|
-
}
|
|
369
|
-
</style>
|
|
370
|
-
\` : '<span style="color:#bfbfbf;font-size:12px;">Never updated</span>';
|
|
371
|
-
\`\`\`
|
|
372
|
-
|
|
373
|
-
## 6. Revenue Potential Progress Bar
|
|
374
|
-
|
|
375
|
-
Displays annual revenue and potential opportunity value, calculates growth potential. Pipeline value is clickable to open opportunities dialog.
|
|
376
|
-
|
|
377
|
-
\`\`\`javascript
|
|
378
|
-
// Revenue potential - Annual revenue + opportunity value with clickable pipeline
|
|
379
|
-
const annualRevenue = ctx.record?.annual_revenue || 0;
|
|
380
|
-
const opportunities = ctx.record?.opportunities || [];
|
|
381
|
-
const potentialValue = opportunities.reduce((sum, opp) => sum + (opp.amount || 0), 0);
|
|
382
|
-
const totalPotential = annualRevenue + potentialValue;
|
|
383
|
-
const hasOpportunities = opportunities.length > 0;
|
|
384
|
-
|
|
385
|
-
const formatCurrency = (val) => {
|
|
386
|
-
if (val >= 1000000) return \`$\${(val/1000000).toFixed(2)}M\`;
|
|
387
|
-
if (val >= 1000) return \`$\${(val/1000).toFixed(1)}K\`;
|
|
388
|
-
return \`$\${val.toFixed(0)}\`;
|
|
389
|
-
};
|
|
390
|
-
|
|
391
|
-
const percentage = annualRevenue > 0 ? Math.min((potentialValue / annualRevenue) * 100, 100) : 0;
|
|
392
|
-
const growthColor = percentage > 50 ? '#52c41a' : percentage > 20 ? '#1677ff' : '#faad14';
|
|
393
|
-
|
|
394
|
-
ctx.element.innerHTML = \`
|
|
395
|
-
<div style="display:flex;flex-direction:column;gap:6px;min-width:150px;">
|
|
396
|
-
<div style="display:flex;justify-content:space-between;align-items:center;">
|
|
397
|
-
<span style="font-size:11px;color:#8c8c8c;">Annual Revenue</span>
|
|
398
|
-
<span style="font-size:13px;color:#000;font-weight:600;">\${formatCurrency(annualRevenue)}</span>
|
|
399
|
-
</div>
|
|
400
|
-
\${potentialValue > 0 ? \`
|
|
401
|
-
<div
|
|
402
|
-
class="pipeline-link"
|
|
403
|
-
style="display:flex;justify-content:space-between;align-items:center;cursor:pointer;padding:2px;border-radius:2px;transition:background 0.2s;"
|
|
404
|
-
onmouseover="this.style.background='#f0f5ff'"
|
|
405
|
-
onmouseout="this.style.background='transparent'"
|
|
406
|
-
>
|
|
407
|
-
<span style="font-size:11px;color:#8c8c8c;">Pipeline (\${opportunities.length})</span>
|
|
408
|
-
<span style="font-size:13px;color:\${growthColor};font-weight:600;">+\${formatCurrency(potentialValue)}</span>
|
|
409
|
-
</div>
|
|
410
|
-
<div style="position:relative;width:100%;height:4px;background:#f0f0f0;border-radius:2px;overflow:hidden;">
|
|
411
|
-
<div style="position:absolute;left:0;top:0;height:100%;width:\${percentage}%;background:\${growthColor};border-radius:2px;"></div>
|
|
412
|
-
</div>
|
|
413
|
-
\` : ''}
|
|
414
|
-
</div>
|
|
415
|
-
\`;
|
|
416
|
-
|
|
417
|
-
// Add click handler for pipeline link
|
|
418
|
-
if (hasOpportunities) {
|
|
419
|
-
const pipelineLink = ctx.element.querySelector('.pipeline-link');
|
|
420
|
-
if (pipelineLink && !pipelineLink._eventBound) {
|
|
421
|
-
pipelineLink._eventBound = true;
|
|
422
|
-
pipelineLink.addEventListener('click', async () => {
|
|
423
|
-
// Open opportunities related to this account
|
|
424
|
-
await ctx.openView('44be52bf4bb', {
|
|
425
|
-
collectionName: 'opportunities',
|
|
426
|
-
dataSourceKey: 'main',
|
|
427
|
-
filterByTk: ctx.record?.id // Filter opportunities by account_id
|
|
428
|
-
});
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
\`\`\`
|
|
433
|
-
|
|
434
|
-
## Usage Instructions
|
|
435
|
-
|
|
436
|
-
### Configuration in NocoBase
|
|
437
|
-
1. Navigate to the table configuration interface
|
|
438
|
-
2. Add a new column and select "JavaScript" type
|
|
439
|
-
3. Paste the corresponding code into the code editor
|
|
440
|
-
4. Save and refresh the table to see the effects
|
|
441
|
-
|
|
442
|
-
### Performance Optimization
|
|
443
|
-
- For columns with complex calculations, limit the number of rows displayed per page
|
|
444
|
-
- Ensure proper query optimization for columns that need to count related data
|
|
445
|
-
- Consider caching results for complex calculations
|
|
446
|
-
|
|
447
|
-
### Customization Tips
|
|
448
|
-
- **Color schemes**: Modify color values to match brand colors
|
|
449
|
-
- **Thresholds**: Adjust health score and activity thresholds based on business needs
|
|
450
|
-
- **Display formats**: Adjust currency and date formats based on regional preferences
|
|
451
|
-
- **Icons**: Replace with other emojis or icon fonts as needed`
|
|
452
|
-
};
|