dreamfactory / df-admin-app
DreamFactory™ 管理控制台
Requires
- dev-master
- 5.0.3
- 5.0.2
- 5.0.1
- 5.0.0
- 4.14.1
- 4.13.0
- 4.12.0
- 4.11.1
- 4.11.0
- 4.10.2
- 4.10.1
- 4.10.0
- 4.9.0
- 4.8.0
- 4.7.2
- 4.7.1
- 4.7.0
- 4.6.0
- 4.5.1
- 4.5.0
- 4.4.0
- 4.3.2
- 4.3.1
- 4.3.0
- 4.2.2
- 4.2.1
- 4.2.0
- 4.1.1
- 4.1.0
- 4.0.3
- 4.0.2
- 4.0.1
- 4.0.0
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- dev-develop / 2.16.x-dev
- 2.16.2
- 2.16.1
- 2.16.0
- 2.15.0
- 2.14.0
- 2.13.0
- 2.12.2
- 2.12.1
- 2.12.0
- 2.11.1
- 2.11.0
- 2.10.0
- 2.9.0
- 2.8.1
- 2.8.0
- 2.7.0
- 2.6.0
- 2.5.1
- 2.5
- 2.4.2
- 2.4.1
- 2.4.0
- 2.3.1
- 2.3.0
- 2.2.3
- 2.2.2
- 2.2.1
- 2.2.0
- 2.1.6
- 2.1.5
- 2.1.4
- 2.1.3
- 2.1.2
- 2.1.1
- 2.1.0
- 2.0.8
- 2.0.7
- 2.0.6
- 2.0.5
- 2.0.4
- 2.0.3
- 2.0.2
- 2.0.1
- 2.0.0
- 0.0.7
- 0.0.6
- 0.0.5
- 0.0.4
- 0.0.3
- 0.0.2
- 0.0.1
- dev-docker-build
- dev-tech-stack-file
- dev-test-DP-312
- dev-dependabot/npm_and_yarn/minimist-0.2.4
- dev-dependabot/npm_and_yarn/minimatch-3.0.8
- dev-dependabot/npm_and_yarn/ua-parser-js-0.7.33
- dev-dependabot/npm_and_yarn/debug-and-grunt-contrib-watch-2.6.9
- dev-dependabot/npm_and_yarn/ms-and-grunt-contrib-watch-2.0.0
- dev-dependabot/npm_and_yarn/qs-and-grunt-contrib-watch-6.5.3
- dev-dependabot/npm_and_yarn/engine.io-6.2.1
- dev-dependabot/npm_and_yarn/socket.io-parser-4.0.5
- dev-DP-312
- dev-DP-501
- dev-DP-290
- dev-DP-351
- dev-dependabot/npm_and_yarn/karma-6.3.16
- dev-DP-453
- dev-DP-416-bigquery
- dev-DP-337
- dev-improvement/remove-app-api-key-constant
- dev-DP-238
- dev-DP-231
- dev-DP-210
- dev-DP-201
- dev-feature/DF-license-3.0-rebase-new-functionality
- dev-3.0-beta
- dev-move-services-to-silver-license(DF-license)
- dev-feature/DF-license-3.0
- dev-feature/DF-shepherd
- dev-feature/DF-tutorial-scripts
- dev-improvement/DF-1318
- dev-bug/DF-1385
This package is auto-updated.
Last update: 2024-09-02 22:52:12 UTC
README
适用于 DreamFactory v2.0 及以上版本的 AngularJS 管理应用程序。
使用此管理应用程序,您可以从任何地方管理 DreamFactory 实例。使用 Bootswatch 主题进行自定义或使用 SCSS/SASS 自定义。使用 Node.js、Grunt 以及包含的 grunt 脚本合并、压缩和丑化组件模块,以创建一个可部署的应用程序。
安装应用程序
克隆存储库。导航到您克隆存储库的顶级目录,并输入 bower install
。 注意:您必须已安装 Node、Grunt 和 GruntCLI。
使用 Node 和 Grunt 构建应用程序
应用程序预装了 grunt 文件,该文件将源文件合并、压缩、丑化、压缩并重新组织为更“传输友好”的方式。它减少了加载时间,并自动清除客户端缓存,以便下次客户端使用时可以看到您的更改,无需手动清除缓存。此过程将创建一个名为 dist
的文件夹,其中包含处理后的应用程序。从现在开始,短语“构建应用程序”是指此过程。要在命令行中运行构建过程,请在应用程序的顶级目录中输入 grunt build
。 注意:您必须已安装 Node、Grunt、GruntCLI 和 Bower。
以下是构建 dist 版本的方法。
一次性设置
install node and npm (downloadable installer)
sudo npm install -g bower
sudo npm install -g grunt-cli
cd ~/repos/df-admin-app (or wherever your repo is)
npm install
bower install (creates sym link app/bower_components)
应用程序使用 Sass/Scss 构建,并使用 Compass 编译。这需要 Ruby 和 Compass。按照此 指南 进行设置。
然后重建 dist 文件夹
grunt build
或者您可以直接使用 Docker 运行开发模式
docker-compose up
使用 Docker 构建
docker-compose run --rm web-dev bash -c "grunt build --force && chmod -R a+rwX ."
最终编译的 CSS 将写入 app/styles/styles.css
。
构建发布版本
这将推送到 master。运行 composer update 将拉取新版本。使用 git-flow 进行发布的基步骤如下。在尝试此操作之前,请确保您本地的 develop 和 master 是最新的。
git checkout master
git pull origin master
git checkout develop
git pull origin develop
git flow release start 2.12.2
在 app/scripts/app.js
中增加应用程序版本。
// Set application version number
.constant('APP_VERSION', '2.12.2')
grunt build
git add --all
git commit -m "Release 2.12.2"
git flow release finish 2.12.2
git push origin develop
git checkout master
git push origin master
git push --tags
从任何地方管理您的 DreamFactory 实例
该应用程序可以配置为从另一台远程服务器管理 DreamFactory 实例。只需打开 app/scripts
目录中包含的 app.js
文件,并将您的 DreamFactory 实例主机名添加到顶部的 INSTANCE_BASE_URL
常量中。现在您可以可选地构建应用程序并将 dist
目录部署。您必须在部署应用程序的 DreamFactory 实例中启用 CORS。
主题应用程序
在 app/styles/sass/partials
中,您可以找到应用程序所有自定义部分的样式表以及 themes
目录中的几个 Bootswatch 模板。所有这些都在 styles.scss
中按特定顺序添加。要更改到不同的 Bootswatch 主题,只需更改 styles.scss
中所有主题名称的出现即可。别忘了运行 grunt build
来编译样式表并构建应用程序。
应用程序架构
该应用程序被设计成具有可插拔的模块。每个模块都包含自己的路由、事件和逻辑,以便移除任何一个模块都不会停止应用程序的工作。这些模块存储在 app/admin_components
之下。为了提高速度,设计了一个模块作为应用程序中频繁使用的数据的中央存储库。许多其他模块依赖于这个模块来获取数据以执行其任务,但经过一点重构,它可以被移除以产生真正独立的模块。
主应用程序
主应用程序文件位于两个目录中。位于 app
目录下的 scripts
和 views
。scripts
目录包含您的 app.js 文件和一个名为 controllers
的子目录,其中包含 main.js
。在上述 views
目录中可以找到 main.js
中定义的控制器对应的视图。app.js
文件包含一些常量。值得注意的是 INSTANCE_BASE_URL
、INSTANCE_API_PREFIX
和 APP_API_KEY
。INSTANCE_BASE_URL
允许设置一个主机,应用程序及其模块将引用该主机进行 API 调用。INSTANCE_API_PREFIX
可以更改以匹配服务器设置。APP_API_KEY
用于以下定义的配置选项中,该选项设置应用程序发出的所有调用的 API 密钥。app.js
还定义了登录、注销、注册的标准路由。这些路由在 main.js
中定义了相应的控制器。
main.js
定义了应用程序特定的控制器。MainCtrl 充当顶级作用域,其他模块可以查询应用程序范围的数据。例如,我们的顶级导航和组件导航链接存储在这里,并以数组的形式传递给渲染链接和控制活动链接高亮的指令。每当添加/删除模块时,其链接都需要在这里处理。但是,您不太可能遇到这种情况(或者根本不会遇到)。
身份验证控制器为身份验证/注册事件提供附加点。它们处理用户管理模块产生的身份验证/注册事件,并实现了稀疏逻辑。这为身份验证/注册的应用特定逻辑和实际验证/注册用户的业务逻辑之间提供了解耦。有关更多信息,请参阅 main.js
的注释。
数据存储库和实用模块
名为 dfApplicationData
的数据存储库模块便于加载和管理频繁使用的应用程序数据。它创建了一个名为 dfApplicationObj
的对象。它包含通用的方法来访问、修改和删除应用程序和服务器中的数据。它还提供了获取和保存实际 dfApplicationObj 的访问器方法。虽然不建议直接与此对象交互,但有时这是必要的恶行。该模块还包含初始化代码,以检查是否需要构建一个新的应用程序对象,或刷新屏幕以使用本地数据,以及要加载哪些 API。
实用模块提供与模块操作相关的服务、工厂、指令和过滤器。像我们的图标服务、导航、表格过滤/分页等存储在这里。基本上,是多个模块可能需要访问的东西,或者没有其他地方可以去。
模块设计
模块按照常规 AngularJS 风格定义。angular.module(MODULE_NAME, [DEPENDENCIES])
。在此行以下,我们为模块定义了一些常量和配置。由于模块通常是小的 SPA,我们只包含了一个主要路由。下面显示 dfApps
模块的子部分来阐述这一点。
// Module definition angular.module('dfApps', ['ngRoute', 'dfUtility', 'dfApplication', 'dfHelp', 'dfTable']) // Path constants are defined to facilitate ease of reorganization .constant('MOD_APPS_ROUTER_PATH', '/apps') .constant('MOD_APPS_ASSET_PATH', 'admin_components/adf-apps/') // A Route for the module is configured and a bit of access logic is included .config(['$routeProvider', 'MOD_APPS_ROUTER_PATH', 'MOD_APPS_ASSET_PATH', function ($routeProvider, MOD_APPS_ROUTER_PATH, MOD_APPS_ASSET_PATH) { $routeProvider .when(MOD_APPS_ROUTER_PATH, { templateUrl: MOD_APPS_ASSET_PATH + 'views/main.html', controller: 'AppsCtrl', resolve: { checkUser:['checkUserService', function (checkUserService) { return checkUserService.checkUser(); }] } }); }]) .run([function () { }]) // More module code
每个组件模块都以这种方式设计。模块通常有一个控制器,其中存储模块导航(侧边栏链接)以及模块标题。
// Module config/routes/constants .controller('AppsCtrl', ['$scope', function($scope) { // Set Title in parent $scope.$parent.title = 'Apps'; // Set module links $scope.links = [ { name: 'manage-apps', label: 'Manage', path: 'manage-apps' }, { name: 'create-app', label: 'Create', path: 'create-app' }, { name: 'import-app', label: 'Import', path: 'import-app' }, { name: 'app-groups', label: 'Groups', path: 'app-groups' } ]; // Set empty section options // additional logic if there are no apps present $scope.emptySectionOptions = { title: 'You have no Apps!', text: 'Click the button below to get started building your first application. You can always create new applications by clicking the tab located in the section menu to the left.', buttonText: 'Create An App!', viewLink: $scope.links[1] }; $scope.$on('$destroy', function (e) { }); }])
每个模块都有一个 main.html
。在 main.html
中将有与模块功能相关的指令。有一个侧边栏导航指令,它接受 links
数组并生成导航。几个 ng-if 语句渲染正确选择的视图。以下是 dfApps
模块的 main.html
文件。
<div> <div class="col-md-2 df-sidebar-nav"> <df-sidebar-nav></df-sidebar-nav> </div> <div class="col-md-10 df-section" df-fs-height > <df-manage-apps data-ng-if="activeView.path === 'manage-apps'"></df-manage-apps> <df-app-details data-ng-if="activeView.path === 'create-app'" data-new-app="true"></df-app-details> <df-import-app data-ng-if="activeView.path === 'import-app'"></df-import-app> </div> </div>
如果您熟悉AngularJS,您会注意到大多数模块的工作是通过指令委派,而不是使用路由和控制器来完成的。虽然这不允许进行深度链接,但它确实提供了通过上下文处理数据的便利性。大多数模块将具有管理和详细上下文,这些上下文被建模为指令,并在与模块文件夹相关的本地存储模板。管理指令将从存储库中提取数据,基于该数据创建一个对象(称为“管理对象”),并以表格形式呈现。通常与“管理对象”关联的行为(例如,管理应用程序对象允许您从其管理对象状态启动托管应用程序)。选择管理对象后,它将被传递给详细指令,该指令将为该类型创建一个对象以进行编辑或创建。当详细指令检测到数据时,管理上下文关闭,详细上下文显示。这通常是一个用于编辑当前选中对象的表单。可以保存、更新或关闭对象,更改将被丢弃。基本的CRUD操作。一旦完成操作,详细上下文可以关闭,管理上下文将再次出现。我们将删除操作保留在管理上下文中,其中可以选择一个或多个对象进行删除。
所有指令(上下文)都以类似的方式工作,即首先将数据传递给它们,然后创建一个包含该数据的对象。传递给指令的数据将始终封装在创建的对象的“record”属性中。我们经常将其他与UI相关的属性附加到该对象上,这些属性可以在__dfUI
属性下找到。以下是详细上下文中App对象的一个示例。
{ __dfUI: { selected: false }, record: { // app data for editing }, recordCopy: { // copied app data for comparison } }
所有表单模型都与记录属性上存储的数据相关联。当我们保存/更新应用程序时,将创建一个新的App对象来替换旧的App对象。然后您可以自由地关闭详细视图或继续编辑。如果您已进行更改并尝试在不保存的情况下关闭,则记录与recordCopy的比较将失败,并提示您“您确定要关闭吗”?这就是大多数工作的方式。非常简单。拉取数据并创建对象。选择要编辑的对象。显示表单以编辑对象。在保存和关闭时进行比较。
上下文组织(我们如何设置指令)
每个指令都以类似的方式组织。请参见下面的示例。
.directive(DIRECTIVE_NAME, [function() { return { restrict: 'E', scope: { thingData: '=' }, templateUrl: CONSTANT_PATH + 'views/TEMPLATE.html', link: function (scope, elem, attrs) { // LOCAL FUNCTIONS: // things pertaining to this directive that won't be shared or stored on scope // Object constructors usually var Thing = function (thingData) { var thingModel = { thingName: 'My Awesome thing name' }; thingData = thingData || thingModel; return { __dfUI: { selected: false, hasError: false }, record: thingData, recordCopy: angular.copy(thingData); } }; scope.theThing = null; // PUBLIC API // Scope functions that attach to our UI // we do preliminary checking here scope.saveThing = function () { if (scope.theThing.__dfUI.hasError) { alert('Thing has error'); return; } scope._saveThing() }; // PRIVATE API // functions stored on/off scope that provide // targeted functionality scope._myPrivFuncOne = function () { // Do someting }; scope._saveThingToServer = function () { // Save thing to server. Return promise }; // COMPLEX IMPLEMENTATION // These scope functions generally are called from the public api // Their names usually correspond with a preceding underscore // We call private api functions targeted for specific tasks // and build our...COMPLEX IMPLEMENTATION of the public function. scope._saveThing = function () { // private func to do someting scope._myPrivFuncOne(); // save thing to server scope._saveThingToServer(scope.theThing).then( function (result) { scope.theThing = new Thing(result.data) }, function (reject) { //report error } ); }; // WATCHERS // place any watchers here var watchThing = scope.$watch('thingData', function (newValue, oldValue) { scope.theThing = new Thing(newValue); }; // MESSAGES // Handle messaging/events here scope.$on('$destroy', function (e) { watchThing(); }; } }])