diff --git a/README.en.md b/README.en.md index 29cabed..10fc11a 100644 --- a/README.en.md +++ b/README.en.md @@ -11,7 +11,7 @@ An efficient intranet office platform that includes various tools such as Word, English | [简体中文](README.md) -[FAQ](./docs/Faq.md) | [API](./docs/Api.md) | [AppStore](./docs/Store.md) +[FAQ](./docs/Faq.md) | [API](./docs/Api.md) | [AppStore](./docs/Store.en.md) ### Install @@ -46,6 +46,8 @@ English | [简体中文](README.md) - ***Small in size, packaged for only 61M, it does include all the office suites*** - ***Unlimited scalability, supports custom applications*** - ***Golang develops backend with low resource consumption and high performance*** +- ***Supports multiple platforms, Windows、Linux、MacOS*** +- ***A complete app store system, simply learn [App Store Configuration](./docs/Store.en.md) to develop complex applications*** ## Function Description @@ -53,65 +55,66 @@ English | [简体中文](README.md) - Exquisite imitation of Windows style - Desktop file management - Support native file drag and drop upload - + ### 2、 File management - Drag and drop file upload - File Search - Native file storage - + ### 3、 Internal chat - No need for complicated registration process, simply discover and list all available chat partners within the same local area network, and start instant messaging immediately. Support LAN based instant messaging, file transfer, and other functions to facilitate seamless communication and collaboration within the team. - + ### 4、 Documents - Simple Word editor, native storage, supports QR codes, handwritten signatures, import and export - + ### 5、 Table - Native storage, Excel editor, supports import and export, supports images and formulas - + ### 6、 Markdown - Native storage, using VDitors, supporting import and export, outline and real-time preview - + ### 7、 Mind map - Built in multiple themes; Support shortcut keys; Node content supports images, icons, hyperlinks, notes, and tags. - + ### 8、 Presentation Presentation - Native storage, using pptist, supporting text, images, shapes, lines, charts, tables, videos, formulas, etc. - + ### 9、 File Editor - Native storage, supports opening text/html/css/js/svg/xml/md, etc., can be used as a simple online editplus. - + ### 10、 Whiteboard - Integrating various creative expression abilities such as free layout, paintbrushes, and notes, it inspires team creativity and enables communication around a whiteboard anytime, anywhere. - + ### 11、 Image editing - A small Photoshop with native storage, supporting image search, cropping, rotation, scaling, filtering, and other functions - + ### 12、 Gantt Chart - A must-have tool for project management, supporting custom project personnel and roles, and supporting drag and drop/management allocation (resources, roles, work), etc. - + ### 13、 Browser - A simple built-in browser - + ### 14、 System settings - You can switch storage methods and system backgrounds here. - + ### 15、 App Store - App store management allows for the addition of external applications. + ### 16、 Screenshot - A simple screenshot tool. Save the screenshot file locally. @@ -121,7 +124,7 @@ English | [简体中文](README.md) ### 18、 Calculator - A calculator that mimics Windows 10 and supports historical records. - + ### 19、 Music Library - A simple sound storage library that supports playing music. @@ -131,7 +134,7 @@ English | [简体中文](README.md) ### 21、 Kanban board - Support standard kanban, a must-have tool for project management, which can quickly create kanban and place it in different folders - + ### 22、 Process management - Support process management, can view process list, kill processes diff --git a/README.md b/README.md index 872746c..b68a5c4 100644 --- a/README.md +++ b/README.md @@ -67,66 +67,67 @@ - 精仿windows风格 - 桌面文件管理 - 支持原生文件拖拽上传 - + ### 二、文件管理 - 文件拖拽上传 - 文件搜索 - 原生文件存储 - 直接压缩/解压文件夹(本地存储支持zip/tar/gz/bz2) - + ### 三、内网聊天 - 无需注册流程,只需在同一内网,即可自动发现并列出所有可用的聊天对象,支持基于局域网的即时消息传输、文件传输等功能。 - + ### 四、文档 - 简便的word编辑器,原生存储,支持二维码、手写签名,导入导出 - + ### 五、表格 - 原生存储,Excel编辑器,支持导入、导出,支持图片、公式 - + ### 六、markdown - 原生存储,采用vditor,支持导入、导出,支持大纲、实时预览 - + ### 七、思维导图 - 内置多种主题;支持快捷键;节点内容支持图片、图标、超链接、备注、标签。 - + ### 八、演示文稿 - 原生存储,采用pptist,支持文字、图片、形状、线条、图表、表格、视频、公式等。 - + ### 九、文件编辑器 - 原生存储,支持打开text/html/css/js/svg/xml/md等,可以当作一个简单的在线editplus。 - + ### 十、白板 - 集自由布局、画笔、便签多种创意表达能力于一体,激发团队创造力,随时随地,围绕一块白板沟通。 - + ### 十一、图片编辑 - 一个小型的photoshop,原生存储,支持搜索图片,支持图片裁剪、旋转、缩放、滤镜等功能 - + ### 十二、甘特图 - 项目管理必备工具,支持自定义项目人员和角色,支持拖拽/管理分配(资源、角色、工作)等。 - + ### 十三、浏览器 - 一款简单的内置浏览器 - + ### 十四、系统设置 - 可在这里切换存储方式,可切换系统背景。 - + ### 十五、应用商店 -- 应用商店管理,丰富的外部接口,可导入/添加/下载外部应用。 +- 应用商店管理,丰富的外部接口,可导入/添加/下载外部应用。支持依赖库安装/卸载。 + ### 十六、截图 - 一个简单的截图工具。截图后文件存到本地。 @@ -136,7 +137,7 @@ ### 十八、计算器 - 一个仿windows10的计算器,支持历史记录。 - + ### 十九、音乐库 - 一个简单的声音存储库,支持播放音乐。 @@ -146,7 +147,7 @@ ### 二十一、看板 - 支持标准看板,项目管理必备工具,可快速创建看板并放置到不同的文件夹 - + ### 二十二、进程管理 - 支持进程管理,可以查看进程列表,杀死进程 diff --git a/docs/Store.en.md b/docs/Store.en.md new file mode 100644 index 0000000..dbec592 --- /dev/null +++ b/docs/Store.en.md @@ -0,0 +1,236 @@ +## GodoOS App Store Development Tutorial + +### Quick Start +1. Download the [mysql5.7 zip package](https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-winx64.zip), and extract it to the `.godoos/run/windows/` directory under the user directory, naming the folder `mysql5.7`. +2. Copy the `mysql5.7` from this program's `docs/demo/mysql5.7` to the `.godoos/run/windows/mysql5.7` directory under the user directory. +3. Open the app store, add an app, select development mode, input `mysql5.7` as the local path, and click OK. + +### Development Requirements + +1. Basic HTML development skills. +2. Familiarity with the executable file startup process, then configure the JSON file according to the following flow. + +### How to Add an Application + +1. Create an application folder under the `.godoos/run/windows/` directory in the user directory. +2. An application requires two configuration files; create the `install.json` and `store.json` files at the root of the application directory. The configuration file formats are as follows: +- `install.json` [Sample](./demo/mysql5.7/install.json) +```json +{ + "name": "", // string, Name of the application. + "url": "", // string, Download URL of the application or adapter package. + "pkg": "", // string, Official download URL of the application. Can be empty. + "webUrl":"", // string, If set, the application will be displayed on the desktop. + "isDev": true, // boolean, Whether it is a development environment. If set to true, data will not be downloaded. + "version": "1.0.0", // string, Version of the application. + "icon": "", // string, Icon of the application, accessible network address. + "hasStart": true, // boolean, Indicates whether startup and shutdown are shown. + "hasRestart": true, // boolean, Whether a restart is needed. + "setting": true // boolean, Whether settings are needed. Only shown when the application is stopped. +} +``` + +- Note: If a web application does not require a backend process, store.json does not need to be configured. +The structure of install.json is: + +```json +type InstallInfo struct { + Name string `json:"name"` // Name of the application. Important, must match the directory name of the application. + URL string `json:"url"` // Download URL of the application or adapter package. + Pkg string `json:"pkg"` // Official download URL of the application. + WebUrl string `json:"webUrl"` // Web address of the application. + IsDev bool `json:"isDev"` // Flag indicating whether it is a developer version. + Version string `json:"version"` // Version number of the application. + Desc string `json:"desc"` // Description information of the application. + Icon string `json:"icon"` // Path to the application icon. + HasStart bool `json:"hasStart"` // Flag indicating whether startup and shutdown are shown. + HasRestart bool `json:"hasRestart"` // Flag indicating whether a restart is needed after installation. + Setting bool `json:"setting"` // Flag indicating whether configuration is needed. + Dependencies []Item `json:"dependencies"` // Dependencies. + History []InstallHastory `json:"history"`// History +} +type InstallHastory struct { + Version string `json:"version"` + URL string `json:"url"` + Pkg string `json:"pkg"` // Official download URL of the application. +} +``` +- store.json [Sample](./demo/mysql5.7/store.json) + +```json +{ + "setting": { + "binPath": "{exePath}/bin/mysqld.exe", // string, Important, must be set. Path to the startup program. + "confPath": "{exePath}/my.ini", // string, Can be empty. Path to the configuration file. + "progressName": "mysqld.exe", // string, Process name. Not required if single-threaded. + "isOn": true // boolean, Whether to start the daemon process. + }, + "config": { // object, Configuration file. Any configuration inside can be filled out, used in conjunction with commands. Can be set via HTTP. + }, + "commands": {}, // object, List of commands. Available for invocation by `installCmds` inside `install`, also callable through external HTTP requests. + "install": { // object, Installation configuration. + "installEnvs": [], // object[], Environment variables. + "installCmds": [] // object[], Startup commands. Can invoke commands from the command list set `commands`. + }, + "start": { + "startEnvs": [], + "beforeCmds": [], // List of commands to execute before startup. Can invoke commands from the command list set `commands`. + "startCmds": [ // object[], Pure parameter command set. Will start `setting.binPath`, cannot invoke commands from the `commands` list. + "--defaults-file={exePath}/my.ini" + ], + "AfterCmds": [] // List of commands to execute after startup. Can invoke commands from the command list set `commands`. + } +} +``` +- Note: The core replacement parameter is `{exePath}`, which is the execution directory of the program. Other `{parameters}` correspond to the config in `store.json`. + + +The structure for `store.json` is as follows: + +```json +type StoreInfo struct { + Setting Setting `json:"setting"` // Configuration information for the application store. + Config map[string]any `json:"config"` // Mapping of application configuration information. + Commands map[string][]Cmd `json:"commands"` // Collection of application commands. + Install InstallStruct `json:"install"` // Information for installing the application. + Start StartStruct `json:"start"` // Information for starting the application. +} +``` +The structure for Setting is: +```json +// Contains critical setting information such as the binary file path and configuration file path of the application. +type Setting struct { + BinPath string `json:"binPath"` // Path to the application's binary file. + ConfPath string `json:"confPath"` // Path to the application's configuration file. + ProgressName string `json:"progressName"` // Name of the process. + IsOn bool `json:"isOn"` // Indicates if the daemon process is running. +} +``` +The structure for Cmd is: +```json +type Cmd struct { + Name string `json:"name"` // Name of the command. + FilePath string `json:"filePath,omitempty"` // Path to the command file. + Content string `json:"content,omitempty"` // Content of the command. + BinPath string `json:"binPath,omitempty"` // Path to the binary file for executing the command. + TplPath string `json:"tplPath,omitempty"` // Template path for the command. + Cmds []string `json:"cmds,omitempty"` // List of subcommands to be executed. + Waiting int `json:"waiting"` // Waiting time. + Kill bool `json:"kill"` // Flag indicating whether to terminate previous commands. If the process name is set in `content`, priority is given to killing the process by name. + Envs []Item `json:"envs"` // Environment variables during command execution. +} +``` +The structure for Install is: +```json +// `InstallStruct` describes environment variables and command lists during the installation process. +type InstallStruct struct { + InstallEnvs []Item `json:"installEnvs"` // Environment variables required during installation. + InstallCmds []string `json:"installCmds"` // List of commands to execute during installation. +} +type StartStruct struct { + StartEnvs []Item `json:"startEnvs"` // Environment variables required during startup. + BeforeCmds []string `json:"beforeCmds"` // List of commands to execute before startup. Commands can be invoked from the `commands` list. + StartCmds []string `json:"startCmds"` // List of commands to execute during startup. + AfterCmds []string `json:"afterCmds"` // List of commands to execute after startup. Commands can be invoked from the `commands` list. +} +// `Item` is a generic key-value pair structure used to represent configuration items or environment variables, etc. +type Item struct { + Name string `json:"name"` // Name of the configuration item. + Value any `json:"value"` // Value of the configuration item. +} +``` + +3. To add an application in the app store, select local addition and input the name of the application directory (no need to fill in the entire directory). + +### Explanation of the Configuration File `store.json` + +1. install can invoke commands from the commands list. +2. Commands in the commands list can also invoke their own commands. +3. All commands can be chained together. + +### How to Set Configuration +1. Create a static directory under the application directory and create an index.html file. Set setting to true in install.json. Frontend configuration example [Sample](./demo/mysql5.7/static/index.html) +```js +const postData = { + dataDir: dataDir, // Corresponds to the config configuration item in store.json + logDir: logDir, // Corresponds to the config configuration item in store.json + port: port, // Corresponds to the config configuration item in store.json + name: "mysql5.7", // Application name + cmdKey: "setting" // Command key, name of cmds +}; +const comp = await fetch('http://localhost:56780/store/setting', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify(postData) +}); +``` +- It is crucial to set name and cmdKey correctly; name is the application name, and cmdKey corresponds to the key in the commands object in store.json. An object can configure a series of commands, which can refer to the structure of Cmd, sample: +```json +"commands": { + "initData": [ + { + "name": "exec", + "binPath": "{exePath}/bin/mysqld.exe", + "cmds": [ + "--defaults-file={exePath}/my.ini", + "--initialize" + ], + "waiting": 1 //Waiting seconds + }, + { + "name": "exec", + "binPath": "{exePath}/bin/mysqld.exe", + "cmds": [ + "--defaults-file={exePath}/my.ini", + "--init-file={exePath}/password.txt" + ], + "waiting": 3, + "content": "mysqld.exe", + "kill": true + }, + { + "name": "start" + } + ], + "setting": [ + { + "name": "changeFile", + "tplPath": "{exePath}/my.ini.tpl", + "filePath": "{exePath}/my.ini" + }, + { + "name": "initData" + } + ], +} +``` +- In the above sample, setting invokes the initData command again. +- The fixed address for POST is http://localhost:56780/store/setting +- The principle works by sending configuration information to the store service through an http request to the /store/setting interface. Then, the store service will automatically update the configuration information and start the application based on the configuration information. + +### Explanation of the static Directory +1. `index.html` is the homepage of the application. +2. When install is executed, files under the static directory are automatically copied to the .godoos/static/ application directory. +3. If store.json sets icon and the file exists in the static directory, the application icon is that file. Otherwise, it is the icon in install.json. + +### Description of Built-in Applications +- The system encapsulates some functions for handling process control and file operations. Below are detailed descriptions of each function: +1. `start` Start the application. +2. `stop` Stop the application. +3. `restart` Restart the application. +4. `exec` Execute a command. Must set binPath and cmds. +5. `writeFile` Write to a file. Must set filePath and content. Based on config, replaces {parameters} in content. +6. `changeFile` Modify a file. Must set filePath and tplPath. Based on config, performs replacements in the template file. +7. `deleteFile` Delete a file. +8. `unzip` Unzip a file. Must set filePath and content. content is the extraction directory. +9. `zip` Compress a file. Must set filePath and content. filePath is the folder to be compressed, and content is the name of the compressed file. +10. `mkdir` Create a directory. Must set FilePath, which is the path of the directory to be created. +11. `startApp` Start another application. content is the name of the application. +12. `stopApp` Stop another application. content is the name of the application. + +### Advanced Operations +1. Download [mysql8.0](https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip) +2. Refer to the mysql8.0 directory under demo and attempt to create your own installation package. + diff --git a/docs/Store.md b/docs/Store.md index 19a404a..0b128b0 100644 --- a/docs/Store.md +++ b/docs/Store.md @@ -18,16 +18,15 @@ ```json { "name": "", // string, 应用程序名称。 - "url": "", // string, 应用程序下载地址。 + "url": "", // string, 应用程序下载地址或适配包的下载地址。 + "pkg": "", // string, 应用程序的官方下载地址。可为空。 "webUrl":"", // string, 如何设置,应用程序将显示到桌面。 "isDev": true, // boolean, 是否为开发环境。如果设置为true将不会下载数据。 - "needDownload": true, // boolean, 是否需要下载,本地开发设置为false。 - "needInstall": true, // boolean, 是否需要安装。 - "version": "1.0.0", // string, 应用程序版本。 + "version": "1.0.0", // string, 应用程序版本。 "icon": "", // string, 应用程序图标,为可访问的网络地址。 - "checkProgress": true, // boolean, 表示是否显示启动和停止。 + "hasStart": true, // boolean, 表示是否显示启动和停止。 "hasRestart": true, // boolean, 是否需要重启。 - "setting": true // boolean, 是否需要设置。 + "setting": true // boolean, 是否需要设置。只有应用停止才会显示。 } ``` @@ -36,19 +35,25 @@ install.json的结构体为: ```json type InstallInfo struct { - Name string `json:"name"` // 应用程序名称。重要,必须和应用的目录名称一致。 - URL string `json:"url"` // 应用程序下载地址。 - WebUrl string `json:"webUrl"` // 应用程序的网页地址。 - IsDev bool `json:"isDev"` // 标志位,表示是否为开发者版本。 - NeedDownload bool `json:"needDownload"` // 标志位,表示是否需要下载。 - NeedInstall bool `json:"needInstall"` // 标志位,表示是否需要安装。 - Version string `json:"version"` // 应用程序的版本号。 - Desc string `json:"desc"` // 应用程序的描述信息。 - Icon string `json:"icon"` // 应用程序的图标路径。 - CheckProgress bool `json:"checkProgress"` // 标志位,表示是否显示启动和停止。 - HasRestart bool `json:"hasRestart"` // 标志位,表示安装后是否需要重启。 - Setting bool `json:"setting"` // 标志位,表示是否需要配置。 - Dependencies []Item `json:"dependencies"` // 依赖项。 + Name string `json:"name"` // 应用程序名称。 + URL string `json:"url"` // 应用程序下载地址或适配包的下载地址。 + Pkg string `json:"pkg"` // 应用程序的官方下载地址。 + WebUrl string `json:"webUrl"` // 应用程序的网页地址。 + IsDev bool `json:"isDev"` // 标志位,表示是否为开发者版本。 + Version string `json:"version"` // 应用程序的版本号。 + Desc string `json:"desc"` // 应用程序的描述信息。 + Icon string `json:"icon"` // 应用程序的图标路径。 + HasStart bool `json:"hasStart"` // 标志位,表示是否显示启动和停止。 + HasRestart bool `json:"hasRestart"` // 标志位,表示安装后是否需要重启。 + Setting bool `json:"setting"` // 标志位,表示是否需要配置。 + Dependencies []Item `json:"dependencies"` // 依赖项。 + Categrory string `json:"category"` // 应用程序的分类。 + History []InstallHastory `json:"history"` // 应用程序的历史版本。 +} +type InstallHastory struct { + Version string `json:"version"` + URL string `json:"url"` + Pkg string `json:"pkg"` // 应用程序的官方下载地址。 } ``` @@ -57,7 +62,6 @@ type InstallInfo struct { ```json { "name": "mysql5.7", // string, 应用程序名称。可不设置,会继承自install.json - "icon": "mysql.png", // string, 应用程序图标,一般放在应用程序static目录下。 "setting": { "binPath": "{exePath}/bin/mysqld.exe", // string, 重要,必须设置。为启动程序路径。 "confPath": "{exePath}/my.ini",// string, 可为空。为配置文件路径。 @@ -84,11 +88,11 @@ type InstallInfo struct { - 备注:核心的替换参数为`{exePath}`即程序的执行目录。其他`{参数}`对应`store.json`里的`config`。 -store.json的struct为 +store.json的结构体为: + ```json type StoreInfo struct { Name string `json:"name"` // 应用程序商店的名称。 - Icon string `json:"icon"` // 应用程序商店的图标路径。 Setting Setting `json:"setting"` // 应用程序商店的配置信息。 Config map[string]any `json:"config"` // 应用程序的配置信息映射。 Commands map[string][]Cmd `json:"commands"` // 应用程序的命令集合。 diff --git a/docs/demo/mysql5.7/install.json b/docs/demo/mysql5.7/install.json index b3dc8db..ef72966 100644 --- a/docs/demo/mysql5.7/install.json +++ b/docs/demo/mysql5.7/install.json @@ -1,12 +1,11 @@ { "name": "mysql5.7", - "url": "https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-winx64.zip", + "pkg": "https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-winx64.zip", + "url": "https://gitee.com/ruitao_admin/godoos-image/releases/download/godoos-store/mysql5.7.zip", "isDev": true, - "needDownload": true, - "needInstall": true, "version": "5.7.44", "icon": "https://img0.baidu.com/it/u=1087008535,3349487719&fm=253&fmt=auto&app=138&f=PNG?w=969&h=500", - "checkProgress": true, + "hasStart": true, "hasRestart": true, "setting": true, "isOn": true diff --git a/docs/demo/mysql5.7/store.json b/docs/demo/mysql5.7/store.json index bb6e1e7..7d8cf10 100644 --- a/docs/demo/mysql5.7/store.json +++ b/docs/demo/mysql5.7/store.json @@ -1,5 +1,4 @@ { - "icon": "mysql.png", "setting": { "binPath": "{exePath}/bin/mysqld.exe", "confPath": "{exePath}/my.ini", diff --git a/docs/demo/mysql8.0/install.json b/docs/demo/mysql8.0/install.json index b9ca128..430ee56 100644 --- a/docs/demo/mysql8.0/install.json +++ b/docs/demo/mysql8.0/install.json @@ -1,12 +1,11 @@ { "name": "mysql8.0", - "url": "https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip", + "pkg": "https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.39-winx64.zip", + "url": "", "isDev": true, - "needDownload": true, - "needInstall": true, "version": "8.0.39", "icon": "https://img0.baidu.com/it/u=1087008535,3349487719&fm=253&fmt=auto&app=138&f=PNG?w=969&h=500", - "checkProgress": true, + "hasStart": true, "hasRestart": true, "setting": true, "isOn": true diff --git a/docs/demo/nginx/store.json b/docs/demo/nginx/store.json index 9e63304..c28578d 100644 --- a/docs/demo/nginx/store.json +++ b/docs/demo/nginx/store.json @@ -1,6 +1,5 @@ { "name": "nginx", - "icon": "nginx.png", "setting": { "binPath": "{exePath}/nginx.exe", "progressName":"nginx.exe" diff --git a/docs/demo/redis5.0/install.json b/docs/demo/redis5.0/install.json deleted file mode 100644 index 740ea8d..0000000 --- a/docs/demo/redis5.0/install.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "redis5.0", - "icon": "redis.png", - "setting": { - "binPath": "{exePath}/redis-server.exe" - }, - "start": { - "startCmds": [ - "{exePath}/redis.windows.conf" - ] - } -} \ No newline at end of file diff --git a/docs/demo/redis5.0/store.json b/docs/demo/redis5.0/store.json index 740ea8d..ce026f0 100644 --- a/docs/demo/redis5.0/store.json +++ b/docs/demo/redis5.0/store.json @@ -1,6 +1,5 @@ { "name": "redis5.0", - "icon": "redis.png", "setting": { "binPath": "{exePath}/redis-server.exe" }, diff --git a/frontend/src/assets/store.scss b/frontend/src/assets/store.scss index e0de62b..4c8ee20 100644 --- a/frontend/src/assets/store.scss +++ b/frontend/src/assets/store.scss @@ -216,17 +216,34 @@ } .main-app { - width: 100%; + width: 96%; /* height: 100%; */ display: flex; + padding:2%; flex-direction: row; flex-wrap: wrap; gap: 10px; justify-content: flex-start; - align-items: flex-start; padding: 10px; - overflow: auto; - align-content: flex-start; +} + +.store-item { + width: calc(33.333% - 10px); /* Subtract the gap size */ + box-sizing: border-box; /* Include padding and border in element's total width */ +} + +/* For screens smaller than 768px, make it one column */ +@media (max-width: 768px) { + .store-item { + width: 100%; + } +} + +/* For screens between 768px and 1024px, make it two columns */ +@media (min-width: 768px) and (max-width: 1024px) { + .store-item { + width: calc(50% - 10px); + } } .store-noready { diff --git a/frontend/src/components/store/AddApp.vue b/frontend/src/components/store/AddApp.vue index c612619..26e92e0 100644 --- a/frontend/src/components/store/AddApp.vue +++ b/frontend/src/components/store/AddApp.vue @@ -22,16 +22,16 @@ const formData = ref({ const progress = ref(0) const addType = [ { - 'name': '远程下载', - 'type': 'download' + name: t('store.remoteDownload'), + type: 'download' }, { - 'name': '本地导入', - 'type': 'local' + name: t('store.localImport'), + type: 'local' }, { - 'name': '开发模式', - 'type': 'dev' + name: t('store.devMode'), + type: 'dev' } ] function selectFile() { @@ -96,15 +96,15 @@ async function upload(e: any) { } const item = await completion.json() //console.log(item) - if(item.data){ + if (item.data) { await installPlugin(item.data) } } } async function addAppByDev() { - if(formData.value.devPath && formData.value.devPath != ""){ + if (formData.value.devPath && formData.value.devPath != "") { await installPlugin(formData.value.devPath) - } + } } async function installPlugin(pluginName: string) { const completion = await fetch(apiUrl + '/store/installInfo?name=' + pluginName) @@ -121,30 +121,31 @@ async function installPlugin(pluginName: string) { diff --git a/frontend/src/components/store/AppItem.vue b/frontend/src/components/store/AppItem.vue index b9eb685..1b110cf 100644 --- a/frontend/src/components/store/AppItem.vue +++ b/frontend/src/components/store/AppItem.vue @@ -1,41 +1,14 @@ - + +