@steedos/service-core-objects 3.0.14-beta.2 → 3.0.14-beta.20

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.
@@ -87,6 +87,17 @@ fields:
87
87
  label: Enable Tree
88
88
  help:
89
89
  description: Enable a tree structure to display records
90
+ tree_expand:
91
+ label: Tree Default Expand
92
+ help:
93
+ options:
94
+ - label: First node only
95
+ value: first
96
+ - label: Expand all
97
+ value: all
98
+ - label: Collapse all
99
+ value: none
100
+ description: Default expansion behavior of the tree list. Defaults to expanding the first node; can be set to expand all nodes or collapse all.
90
101
  enable_enhanced_lookup:
91
102
  label: Enable Enhanced Lookup
92
103
  help:
@@ -91,6 +91,17 @@ fields:
91
91
  label: 树状结构显示
92
92
  help:
93
93
  description: 以树状格式呈现数据层级结构,方便查看记录的父子关系。
94
+ tree_expand:
95
+ label: 树列表默认展开
96
+ help:
97
+ options:
98
+ - label: 仅展开首个节点
99
+ value: first
100
+ - label: 全部展开
101
+ value: all
102
+ - label: 全部收起
103
+ value: none
104
+ description: 配置开启树状结构显示后,列表加载时的默认展开行为。默认展开第一个节点;可选择默认展开全部节点或全部收起。
94
105
  enable_enhanced_lookup:
95
106
  label: 弹出窗口查找
96
107
  help:
@@ -220,6 +220,22 @@ fields:
220
220
  label: Enable Tree
221
221
  sort_no: 200
222
222
  type: boolean
223
+ tree_expand:
224
+ name: tree_expand
225
+ group: advanced
226
+ hidden: false
227
+ label: Tree Default Expand
228
+ sort_no: 205
229
+ type: select
230
+ defaultValue: first
231
+ options:
232
+ - label: Expand First
233
+ value: first
234
+ - label: Expand All
235
+ value: all
236
+ - label: Collapse All
237
+ value: none
238
+ visible_on: '{{ formData.enable_tree == true }}'
223
239
  enable_workflow:
224
240
  name: enable_workflow
225
241
  defaultValue: true
@@ -4,9 +4,15 @@
4
4
  "body": [
5
5
  {
6
6
  "type": "liquid",
7
- "template": "<style>\n /* --- 基础设置 --- */\n .steedos-ios-launcher {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n user-select: none;\n }\n\n .no-scrollbar::-webkit-scrollbar {\n display: none;\n }\n\n .no-scrollbar {\n -ms-overflow-style: none;\n scrollbar-width: none;\n }\n\n /* --- 动画定义 --- */\n @keyframes blob-bounce {\n 0% {\n transform: translate(0, 0) scale(1);\n }\n\n 33% {\n transform: translate(30px, -50px) scale(1.1);\n }\n\n 66% {\n transform: translate(-20px, 20px) scale(0.9);\n }\n\n 100% {\n transform: translate(0, 0) scale(1);\n }\n }\n\n .animate-blob {\n animation: blob-bounce 10s infinite ease-in-out;\n }\n\n @keyframes fade-in-up {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .animate-fade-in-up {\n animation: fade-in-up 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;\n }\n\n /* --- 交互样式 --- */\n .app-icon-container {\n transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s;\n will-change: transform;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .app-item:not(.static-item):hover .app-icon-container {\n transform: scale(1.05);\n box-shadow: 0 15px 30px -5px rgba(0, 0, 0, 0.1);\n z-index: 10;\n }\n\n .app-item.static-item:hover .app-icon-container {\n transform: scale(1.05);\n background-color: rgba(255, 255, 255, 0.8);\n }\n\n .sortable-drag .app-icon-container {\n transform: scale(1.15) !important;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.35);\n filter: brightness(1.02);\n cursor: grabbing;\n }\n\n .sortable-ghost {\n opacity: 0;\n }\n\n /* 加载状态 */\n .loading-skeleton {\n animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n background-color: rgba(255, 255, 255, 0.5);\n border-radius: 1.6rem;\n }\n\n @keyframes pulse {\n\n 0%,\n 100% {\n opacity: 1;\n }\n\n 50% {\n opacity: .5;\n }\n }\n</style>\n\n<div id=\"launcher-container\"\n class=\"steedos-ios-launcher relative w-full h-screen bg-[#F5F7FA] text-slate-800 overflow-hidden\">\n\n <div\n class=\"absolute top-0 left-0 w-[500px] h-[500px] bg-blue-300/30 rounded-full mix-blend-multiply filter blur-[80px] opacity-70 animate-blob pointer-events-none\">\n </div>\n <div class=\"absolute top-0 right-0 w-[500px] h-[500px] bg-purple-300/30 rounded-full mix-blend-multiply filter blur-[80px] opacity-70 animate-blob pointer-events-none\"\n style=\"animation-delay: 2s\"></div>\n <div class=\"absolute -bottom-32 left-20 w-[500px] h-[500px] bg-pink-300/30 rounded-full mix-blend-multiply filter blur-[80px] opacity-70 animate-blob pointer-events-none\"\n style=\"animation-delay: 4s\"></div>\n\n <div class=\"relative z-10 w-full h-full flex flex-col items-center pt-32 pb-10 px-6 overflow-y-auto no-scrollbar\"\n id=\"main-scroll-area\">\n <div id=\"vibrant-grid\"\n class=\"grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-x-6 gap-y-10 w-full max-w-6xl px-2 pb-20 animate-fade-in-up\"\n style=\"animation-delay: 0.1s;\">\n </div>\n </div>\n</div>\n\n<script>\n // ==========================================\n // ✅ 在这里编写您的业务逻辑\n // ==========================================\n \n // 1. 点击“应用市场”按钮时触发\n window.handleAppStoreClick = function() {\n // --- 请在此处编写代码 ---\n console.log(\"点击了应用市场\");\n window.location.href = \"/app/admin/page/app_store\"; \n };\n\n // 2. 点击列表末尾“添加应用”图标时触发\n window.handleAddAppClick = function() {\n // --- 请在此处编写代码 ---\n console.log(\"点击了添加应用\");\n data._scoped.doAction([{\n actionType: 'click',\n componentId: 'buttonAddApp',\n }])\n };\n\n\n // ==========================================\n // 下方为系统核心代码 (一般无需修改)\n // ==========================================\n \n var STORE_KEY = 'steedos_launcher_order';\n var COLOR_MAP = {\n 'red': 'from-red-400 to-rose-600 shadow-red-500/20',\n 'orange': 'from-orange-400 to-red-500 shadow-orange-500/20',\n 'yellow': 'from-amber-400 to-orange-500 shadow-amber-500/20',\n 'green': 'from-green-400 to-emerald-600 shadow-green-500/20',\n 'teal': 'from-teal-400 to-teal-600 shadow-teal-500/20',\n 'cyan': 'from-cyan-400 to-blue-500 shadow-cyan-500/20',\n 'sky': 'from-sky-400 to-blue-500 shadow-sky-500/20',\n 'blue': 'from-blue-400 to-indigo-600 shadow-blue-500/20',\n 'purple': 'from-violet-400 to-purple-600 shadow-violet-500/20',\n 'pink': 'from-pink-400 to-rose-600 shadow-pink-500/20',\n 'gray': 'from-slate-500 to-slate-700 shadow-slate-500/20',\n 'default':'from-sky-400 to-blue-500 shadow-sky-500/20' \n };\n\n function saveAppOrder(orderArray) {\n var cleanOrder = orderArray.filter(function(id) { return id !== 'add'; });\n localStorage.setItem(STORE_KEY, JSON.stringify(cleanOrder));\n }\n\n function createAppHtml(app) {\n var colorKey = app.color;\n if (!colorKey) colorKey = 'sky';\n if (app.id === 'admin' && !app.color) colorKey = 'gray';\n var bgClass = COLOR_MAP[colorKey] || COLOR_MAP['sky'];\n\n var iconName = app.icon || 'account'; \n var iconPath = '/assets/icons/standard-sprite/svg/symbols.svg#' + iconName;\n\n // 使用转义的模板字符串\n return `\n <div class=\"app-item group flex flex-col items-center select-none\" \n data-id=\"\\${app.id}\" \n onclick=\"window.location.href='\\${app.path}'\">\n <div class=\"app-icon-container relative w-20 h-20 md:w-24 md:h-24 rounded-[1.6rem] bg-gradient-to-br \\${bgClass} text-white\">\n <div class=\"absolute top-0 left-0 right-0 h-1/2 bg-gradient-to-b from-white/20 to-transparent rounded-t-[1.6rem] pointer-events-none\"></div>\n <svg class=\"w-11 h-11 md:w-14 md:h-14 drop-shadow-sm\" aria-hidden=\"true\" fill=\"currentColor\">\n <use xlink:href=\"\\${iconPath}\"></use>\n </svg>\n </div>\n <span class=\"mt-3 text-xs md:text-sm font-semibold text-slate-600 group-hover:text-slate-900 transition-colors text-center line-clamp-1\">\\${app.name}</span>\n </div>\n `;\n }\n\n // ✅ 2. 生成添加按钮 (已绑定 handleAddAppClick)\n function createAddBtnHtml() {\n return `\n <div class=\"app-item group flex flex-col items-center select-none static-item\" data-id=\"add\" onclick=\"handleAddAppClick()\">\n <div class=\"app-icon-container relative w-20 h-20 md:w-24 md:h-24 rounded-[1.6rem] border-2 border-dashed border-slate-300 bg-white/50 backdrop-blur-sm text-slate-400\">\n <svg class=\"w-11 h-11 md:w-14 md:h-14\" aria-hidden=\"true\" fill=\"currentColor\">\n <use xlink:href=\"/assets/icons/utility-sprite/svg/symbols.svg#add\"></use>\n </svg>\n </div>\n <span class=\"mt-3 text-xs md:text-sm font-semibold text-slate-500\">添加应用</span>\n </div>\n `;\n }\n\n (async function initLauncher() {\n var gridElement = document.getElementById('vibrant-grid');\n var skeletonHtml = '';\n for(var i=0; i<6; i++) { skeletonHtml += `<div class=\"w-20 h-20 md:w-24 md:h-24 loading-skeleton mx-auto\"></div>`; }\n gridElement.innerHTML = skeletonHtml;\n\n try {\n var response = await fetch('/service/api/apps/menus?mobile=false');\n if (!response.ok) throw new Error('Failed to fetch apps');\n var appsData = await response.json();\n\n var savedOrderStr = localStorage.getItem(STORE_KEY);\n var finalApps = [];\n \n if (savedOrderStr) {\n var savedOrderIds = JSON.parse(savedOrderStr);\n savedOrderIds.forEach(function(id) {\n var app = appsData.find(function(a) { return a.id === id; });\n if (app) finalApps.push(app);\n });\n appsData.forEach(function(app) {\n if (savedOrderIds.indexOf(app.id) === -1) finalApps.push(app);\n });\n } else {\n finalApps = appsData;\n }\n\n var htmlContent = finalApps.map(function(app) { return createAppHtml(app); }).join('');\n htmlContent += createAddBtnHtml(); \n gridElement.innerHTML = htmlContent;\n\n if (typeof Sortable !== 'undefined') {\n new Sortable(gridElement, {\n animation: 350,\n easing: \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n delay: 0,\n delayOnTouchOnly: true,\n ghostClass: 'sortable-ghost',\n dragClass: 'sortable-drag',\n filter: \".static-item\", \n onMove: function (evt) { return evt.related.className.indexOf('static-item') === -1; },\n onEnd: function (evt) {\n var newOrder = [];\n var currentItems = gridElement.querySelectorAll('.app-item');\n currentItems.forEach(function(item) {\n var id = item.getAttribute('data-id');\n if (id && id !== 'add') newOrder.push(id);\n });\n saveAppOrder(newOrder);\n }\n });\n }\n } catch (error) {\n console.error(\"Launcher Error:\", error);\n gridElement.innerHTML = `<div class=\"col-span-full text-center text-slate-400\">加载失败<br><span class=\"text-xs opacity-70\">\\${error.message}</span></div>`;\n }\n })();\n</script>",
7
+ "template": "<style>\n .steedos-launcher {\n font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Display', 'Segoe UI', sans-serif;\n -webkit-font-smoothing: antialiased;\n -webkit-user-select: none;\n user-select: none;\n }\n\n .no-scrollbar::-webkit-scrollbar { display: none; }\n .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }\n\n .app-icon-box {\n transition: transform 0.18s ease, box-shadow 0.18s ease;\n will-change: transform;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .app-item:not(.static-item):hover .app-icon-box {\n transform: scale(1.06);\n box-shadow: 0 8px 24px -4px rgba(0,0,0,0.12);\n }\n\n .app-item:not(.static-item):active .app-icon-box {\n transform: scale(0.97);\n box-shadow: 0 2px 8px rgba(0,0,0,0.08);\n }\n\n .app-item.static-item:hover .app-icon-box {\n background-color: rgba(0,0,0,0.04);\n }\n\n .sortable-drag .app-icon-box {\n transform: scale(1.1) !important;\n box-shadow: 0 20px 40px -8px rgba(0,0,0,0.18);\n cursor: grabbing;\n }\n\n .sortable-ghost { opacity: 0; }\n\n .loading-skeleton {\n animation: sk-pulse 1.6s ease-in-out infinite;\n background-color: rgba(0,0,0,0.06);\n border-radius: 1.25rem;\n }\n\n @keyframes sk-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n }\n</style>\n\n<div id=\"launcher-container\" class=\"steedos-launcher relative w-full text-neutral-800\">\n <div class=\"relative z-10 w-full flex flex-col items-center pt-6 pb-4 px-4 no-scrollbar\" id=\"main-scroll-area\">\n <div id=\"vibrant-grid\"\n class=\"bg-white rounded-xl shadow-sm grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 xl:grid-cols-8 gap-x-5 gap-y-6 w-full max-w-4xl mx-auto py-6 px-8\">\n </div>\n </div>\n</div>\n\n<script>\n window.navigateTo = function(path) {\n if (!path) return;\n if (path.startsWith('/') || path.startsWith(window.location.origin)) {\n try {\n var url = new URL(path, window.location.origin);\n window.navigate(url.pathname + url.search + url.hash);\n } catch(e) {\n window.navigate(path);\n }\n } else {\n window.location.href = path;\n }\n };\n\n window.handleAppStoreClick = function() {\n window.navigateTo(\"/app/admin/page/app_store\");\n };\n\n window.handleAddAppClick = function() {\n data._scoped.doAction([{\n actionType: 'click',\n componentId: 'buttonAddApp',\n }])\n };\n\n var STORE_KEY = 'steedos_launcher_order';\n var COLOR_MAP = {\n 'red': 'bg-red-500',\n 'orange': 'bg-orange-500',\n 'yellow': 'bg-amber-500',\n 'green': 'bg-emerald-500',\n 'teal': 'bg-teal-500',\n 'cyan': 'bg-cyan-500',\n 'sky': 'bg-sky-500',\n 'blue': 'bg-blue-500',\n 'purple': 'bg-violet-500',\n 'pink': 'bg-pink-500',\n 'gray': 'bg-neutral-500',\n 'default':'bg-sky-500'\n };\n\n function saveAppOrder(orderArray) {\n var cleanOrder = orderArray.filter(function(id) { return id !== 'add'; });\n localStorage.setItem(STORE_KEY, JSON.stringify(cleanOrder));\n }\n\n function createAppHtml(app) {\n var colorKey = app.color;\n if (!colorKey) colorKey = 'sky';\n if (app.id === 'admin' && !app.color) colorKey = 'gray';\n var bgClass = COLOR_MAP[colorKey] || COLOR_MAP['sky'];\n\n var iconName = app.icon || 'account';\n var iconPath = '/assets/icons/standard-sprite/svg/symbols.svg#' + iconName;\n\n return `\n <div class=\"app-item group flex flex-col items-center select-none\"\n data-id=\"\\${app.id}\"\n onclick=\"window.navigateTo('\\${app.path}')\">\n <div class=\"app-icon-box relative w-16 h-16 md:w-[72px] md:h-[72px] rounded-2xl \\${bgClass} text-white shadow-sm\">\n <svg class=\"w-9 h-9 md:w-10 md:h-10\" aria-hidden=\"true\" fill=\"currentColor\">\n <use xlink:href=\"\\${iconPath}\"></use>\n </svg>\n </div>\n <span class=\"mt-2 text-[11px] md:text-xs text-neutral-500 group-hover:text-neutral-800 transition-colors text-center leading-tight line-clamp-2 w-16 md:w-[72px]\">\\${app.name}</span>\n </div>\n `;\n }\n\n function createAddBtnHtml() {\n return `\n <div class=\"app-item group flex flex-col items-center select-none static-item\" data-id=\"add\" onclick=\"handleAddAppClick()\">\n <div class=\"app-icon-box relative w-16 h-16 md:w-[72px] md:h-[72px] rounded-2xl border border-dashed border-neutral-300 text-neutral-300\">\n <svg class=\"w-8 h-8 md:w-9 md:h-9\" aria-hidden=\"true\" fill=\"currentColor\">\n <use xlink:href=\"/assets/icons/utility-sprite/svg/symbols.svg#add\"></use>\n </svg>\n </div>\n <span class=\"mt-2 text-[11px] md:text-xs text-neutral-400\">添加应用</span>\n </div>\n `;\n }\n\n (async function initLauncher() {\n var gridElement = document.getElementById('vibrant-grid');\n var skeletonHtml = '';\n for(var i=0; i<8; i++) { skeletonHtml += '<div class=\"w-16 h-16 md:w-[72px] md:h-[72px] loading-skeleton mx-auto\"></div>'; }\n gridElement.innerHTML = skeletonHtml;\n\n try {\n var isMobile = window.innerWidth < 768;\n var response = await fetch('/service/api/apps/menus?mobile=' + isMobile);\n if (!response.ok) throw new Error('Failed to fetch apps');\n var appsData = (await response.json()).filter(function(a) { return a.id !== 'desktop'; });\n\n var savedOrderStr = localStorage.getItem(STORE_KEY);\n var finalApps = [];\n\n if (savedOrderStr) {\n var savedOrderIds = JSON.parse(savedOrderStr);\n savedOrderIds.forEach(function(id) {\n var app = appsData.find(function(a) { return a.id === id; });\n if (app) finalApps.push(app);\n });\n appsData.forEach(function(app) {\n if (savedOrderIds.indexOf(app.id) === -1) finalApps.push(app);\n });\n } else {\n finalApps = appsData;\n }\n\n var htmlContent = finalApps.map(function(app) { return createAppHtml(app); }).join('');\n htmlContent += createAddBtnHtml();\n gridElement.innerHTML = htmlContent;\n\n if (typeof Sortable !== 'undefined') {\n new Sortable(gridElement, {\n animation: 300,\n easing: \"ease\",\n delay: 0,\n delayOnTouchOnly: true,\n ghostClass: 'sortable-ghost',\n dragClass: 'sortable-drag',\n filter: \".static-item\",\n onMove: function (evt) { return evt.related.className.indexOf('static-item') === -1; },\n onEnd: function (evt) {\n var newOrder = [];\n var currentItems = gridElement.querySelectorAll('.app-item');\n currentItems.forEach(function(item) {\n var id = item.getAttribute('data-id');\n if (id && id !== 'add') newOrder.push(id);\n });\n saveAppOrder(newOrder);\n }\n });\n }\n } catch (error) {\n console.error(\"Launcher Error:\", error);\n gridElement.innerHTML = '<div class=\"col-span-full text-center text-neutral-400 py-20\">加载失败<br><span class=\"text-xs opacity-60\">' + error.message + '</span></div>';\n }\n })();\n</script>",
8
8
  "id": "u:04103f69c7d4"
9
9
  },
10
+ {
11
+ "type": "service",
12
+ "schemaApi": "get:/service/api/@steedos/service-pages/page/app_launcher/widget_schema",
13
+ "id": "u:app_launcher_widgets",
14
+ "className": "w-full max-w-4xl mx-auto p-0 m-0"
15
+ },
10
16
  {
11
17
  "type": "button",
12
18
  "label": "按钮",
@@ -3,7 +3,6 @@
3
3
  <script src="/unpkg.com/@steedos-builder/fiddle@0.0.5/dist/builder-fiddle.umd.js"></script>
4
4
  <script src="/unpkg.com/axios@0.26.1/dist/axios.min.js"></script>
5
5
  <script src="https://unpkg.steedos.cn/flowbite@2.3.0/dist/flowbite.min.js"></script>
6
- <script src="https://cdn.tailwindcss.com"></script>
7
6
  <link href="/toast/toastr.min.css" rel="stylesheet" />
8
7
  <script src="/jquery.min.js" ></script>
9
8
  <script src="/toast/toastr.min.js"></script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steedos/service-core-objects",
3
- "version": "3.0.14-beta.2",
3
+ "version": "3.0.14-beta.20",
4
4
  "main": "package.service.js",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -9,7 +9,7 @@
9
9
  "steedos"
10
10
  ],
11
11
  "dependencies": {
12
- "@steedos/service-package-loader": "3.0.14-beta.2",
12
+ "@steedos/service-package-loader": "3.0.14-beta.20",
13
13
  "bcryptjs": "^3.0.3",
14
14
  "json2xls": "^0.1.2",
15
15
  "lodash": "^4.17.21"
@@ -17,5 +17,5 @@
17
17
  "description": "steedos package",
18
18
  "repository": {},
19
19
  "license": "MIT",
20
- "gitHead": "840ce631d505348bbfdbd5c0b728b3661c4dd36d"
20
+ "gitHead": "96e541f24fe9f1ed58ca04c7e631a0d795a0147f"
21
21
  }