├── .bowerrc
├── .gitignore
├── .jshintrc
├── .travis.yml
├── README.md
├── app
├── app.css
├── app.js
├── components
│ └── version
│ │ ├── interpolate-filter.js
│ │ ├── interpolate-filter_test.js
│ │ ├── version-directive.js
│ │ ├── version-directive_test.js
│ │ ├── version.js
│ │ └── version_test.js
├── dialog.tmpl.html
├── home
│ ├── home.html
│ └── home.js
├── img
│ └── icons
│ │ ├── ic_add_24px.svg
│ │ ├── ic_close_24px.svg
│ │ ├── ic_done_24px.svg
│ │ ├── ic_done_all_24px.svg
│ │ ├── ic_menu_24px.svg
│ │ └── ic_refresh_24px.svg
├── index.html
└── view1
│ ├── view1.html
│ └── view1.js
├── bower.json
├── dist
├── .gitkeep
├── app.css
├── app.js
├── components
│ └── version
│ │ ├── interpolate-filter.js
│ │ ├── interpolate-filter_test.js
│ │ ├── version-directive.js
│ │ ├── version-directive_test.js
│ │ ├── version.js
│ │ └── version_test.js
├── dialog.tmpl.html
├── home
│ ├── home.html
│ └── home.js
├── img
│ └── icons
│ │ ├── ic_add_24px.svg
│ │ ├── ic_close_24px.svg
│ │ ├── ic_done_24px.svg
│ │ ├── ic_done_all_24px.svg
│ │ ├── ic_menu_24px.svg
│ │ └── ic_refresh_24px.svg
├── index.html
├── view1
│ ├── view1.html
│ ├── view1.js
│ └── view1_test.js
└── view2
│ ├── view2.html
│ ├── view2.js
│ └── view2_test.js
├── e2e-tests
├── protractor.conf.js
└── scenarios.js
├── karma.conf.js
└── package.json
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "app/bower_components"
3 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | logs/*
2 | !.gitkeep
3 | node_modules/
4 | bower_components/
5 | tmp
6 | .DS_Store
7 | .idea
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "globalstrict": true,
3 | "globals": {
4 | "angular": false,
5 | "describe": false,
6 | "it": false,
7 | "expect": false,
8 | "beforeEach": false,
9 | "afterEach": false,
10 | "module": false,
11 | "inject": false
12 | }
13 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 |
5 | before_script:
6 | - export DISPLAY=:99.0
7 | - sh -e /etc/init.d/xvfb start
8 | - npm start > /dev/null &
9 | - npm run update-webdriver
10 | - sleep 1 # give server time to start
11 |
12 | script:
13 | - node_modules/.bin/karma start karma.conf.js --no-auto-watch --single-run --reporters=dots --browsers=Firefox
14 | - node_modules/.bin/protractor e2e-tests/protractor.conf.js --browser=firefox
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | material-angular-demo-project
2 | =============================
3 |
4 | Проект для демонстрации material-angular
5 |
6 | ### Install Dependencies
7 |
8 | We have two kinds of dependencies in this project: tools and angular framework code. The tools help
9 | us manage and test the application.
10 |
11 | * We get the tools we depend upon via `npm`, the [node package manager][npm].
12 | * We get the angular code via `bower`, a [client-side code package manager][bower].
13 |
14 | We have preconfigured `npm` to automatically run `bower` so we can simply do:
15 |
16 | ```
17 | npm install
18 | ```
19 |
20 | Behind the scenes this will also call `bower install`. You should find that you have two new
21 | folders in your project.
22 |
23 | * `node_modules` - contains the npm packages for the tools we need
24 | * `app/bower_components` - contains the angular framework files
25 |
26 | *Note that the `bower_components` folder would normally be installed in the root folder but
27 | angular-seed changes this location through the `.bowerrc` file. Putting it in the app folder makes
28 | it easier to serve the files by a webserver.*
29 |
30 | ### Run the Application
31 |
32 | We have preconfigured the project with a simple development web server. The simplest way to start
33 | this server is:
34 |
35 | ```
36 | npm start
37 | ```
38 |
39 | Now browse to the app at `http://localhost:8888/app/index.html`.
40 |
41 |
42 | The angular-seed app comes with end-to-end tests, again written in [Jasmine][jasmine]. These tests
43 | are run with the [Protractor][protractor] End-to-End test runner. It uses native events and has
44 | special features for Angular applications.
45 |
46 | * the configuration is found at `e2e-tests/protractor-conf.js`
47 | * the end-to-end tests are found in `e2e-tests/scenarios.js`
48 |
49 | Protractor simulates interaction with our web app and verifies that the application responds
50 | correctly. Therefore, our web server needs to be serving up the application, so that Protractor
51 | can interact with it.
52 |
53 | ```
54 | npm start
55 | ```
56 |
57 | In addition, since Protractor is built upon WebDriver we need to install this. The angular-seed
58 | project comes with a predefined script to do this:
59 |
60 | ```
61 | npm run update-webdriver
62 | ```
63 |
64 | This will download and install the latest version of the stand-alone WebDriver tool.
65 |
66 | Once you have ensured that the development web server hosting our application is up and running
67 | and WebDriver is updated, you can run the end-to-end tests using the supplied npm script:
68 |
69 | ```
70 | npm run protractor
71 | ```
72 |
73 | This script will execute the end-to-end tests against the application being hosted on the
74 | development server.
75 |
76 |
77 | ## Updating Angular
78 |
79 | Previously we recommended that you merge in changes to angular-seed into your own fork of the project.
80 | Now that the angular framework library code and tools are acquired through package managers (npm and
81 | bower) you can use these tools instead to update the dependencies.
82 |
83 | You can update the tool dependencies by running:
84 |
85 | ```
86 | npm update
87 | ```
88 |
89 | This will find the latest versions that match the version ranges specified in the `package.json` file.
90 |
91 | You can update the Angular dependencies by running:
92 |
93 | ```
94 | bower update
95 | ```
96 |
97 | This will find the latest versions that match the version ranges specified in the `bower.json` file.
98 |
99 |
100 | ## Loading Angular Asynchronously
101 |
102 | The angular-seed project supports loading the framework and application scripts asynchronously. The
103 | special `index-async.html` is designed to support this style of loading. For it to work you must
104 | inject a piece of Angular JavaScript into the HTML page. The project has a predefined script to help
105 | do this.
106 |
107 | ```
108 | npm run update-index-async
109 | ```
110 |
111 | This will copy the contents of the `angular-loader.js` library file into the `index-async.html` page.
112 | You can run this every time you update the version of Angular that you are using.
113 |
114 |
115 | ## Serving the Application Files
116 |
117 | While angular is client-side-only technology and it's possible to create angular webapps that
118 | don't require a backend server at all, we recommend serving the project files using a local
119 | webserver during development to avoid issues with security restrictions (sandbox) in browsers. The
120 | sandbox implementation varies between browsers, but quite often prevents things like cookies, xhr,
121 | etc to function properly when an html page is opened via `file://` scheme instead of `http://`.
122 |
123 |
124 | ### Running the App during Development
125 |
126 | The angular-seed project comes preconfigured with a local development webserver. It is a node.js
127 | tool called [http-server][http-server]. You can start this webserver with `npm start` but you may choose to
128 | install the tool globally:
129 |
130 | ```
131 | sudo npm install -g http-server
132 | ```
133 |
134 | Then you can start your own development web server to serve static files from a folder by
135 | running:
136 |
137 | ```
138 | http-server -a localhost -p 8888
139 | ```
140 |
141 | Alternatively, you can choose to configure your own webserver, such as apache or nginx. Just
142 | configure your server to serve the files under the `app/` directory.
143 |
144 |
145 | ### Running the App in Production
146 |
147 | This really depends on how complex your app is and the overall infrastructure of your system, but
148 | the general rule is that all you need in production are all the files under the `app/` directory.
149 | Everything else should be omitted.
150 |
151 | Angular apps are really just a bunch of static html, css and js files that just need to be hosted
152 | somewhere they can be accessed by browsers.
153 |
154 | If your Angular app is talking to the backend server via xhr or other means, you need to figure
155 | out what is the best way to host the static files to comply with the same origin policy if
156 | applicable. Usually this is done by hosting the files by the backend server or through
157 | reverse-proxying the backend server(s) and webserver(s).
158 |
159 |
160 | ## Continuous Integration
161 |
162 | ### Travis CI
163 |
164 | [Travis CI][travis] is a continuous integration service, which can monitor GitHub for new commits
165 | to your repository and execute scripts such as building the app or running tests. The angular-seed
166 | project contains a Travis configuration file, `.travis.yml`, which will cause Travis to run your
167 | tests when you push to GitHub.
168 |
169 | You will need to enable the integration between Travis and GitHub. See the Travis website for more
170 | instruction on how to do this.
171 |
172 | ### CloudBees
173 |
174 | CloudBees have provided a CI/deployment setup:
175 |
176 |
177 |
178 |
179 | If you run this, you will get a cloned version of this repo to start working on in a private git repo,
180 | along with a CI service (in Jenkins) hosted that will run unit and end to end tests in both Firefox and Chrome.
181 |
182 |
183 | ## Contact
184 |
185 | For more information on AngularJS please check out http://angularjs.org/
186 |
187 | [git]: http://git-scm.com/
188 | [bower]: http://bower.io
189 | [npm]: https://www.npmjs.org/
190 | [node]: http://nodejs.org
191 | [protractor]: https://github.com/angular/protractor
192 | [jasmine]: http://jasmine.github.io
193 | [karma]: http://karma-runner.github.io
194 | [travis]: https://travis-ci.org/
195 | [http-server]: https://github.com/nodeapps/http-server
196 |
--------------------------------------------------------------------------------
/app/app.css:
--------------------------------------------------------------------------------
1 | /* app css stylesheet */
2 | body {
3 | height: none;
4 | background-color: #E7E7E7;
5 | }
6 |
7 | .box {
8 | width: 200px;
9 | height: 200px;
10 | background-color: yellow;
11 |
12 | }
13 |
14 | .fix-top {
15 | position: fixed;
16 | top:0;
17 | }
18 |
19 | .nornal-btn {
20 | width: 56px;
21 | height: 56px;
22 | }
23 |
24 | .nornal-round-btn {
25 | width: 56px;
26 | height: 56px;
27 | border-radius: 50%;
28 | }
29 |
30 | .float-btn {
31 | height:56px;
32 | width: 56px;
33 | position: fixed;
34 | bottom: 55px;
35 | right: 55px;
36 | }
37 |
38 | md-whiteframe {
39 | background: #fff;
40 | margin: 20px;
41 | padding: 20px;
42 | }
43 |
44 | .check {
45 | background-color: #E8EAF6;
46 | }
47 | .left-box {
48 | width:56px; height: 56px; padding:0; background-color: gray; border-radius: 50%;
49 | }
50 | .active-checkbox {
51 | background-color: transparent !important;
52 | }
53 |
54 | core-tooltip.fancy::shadow .core-tooltip {
55 | opacity: 0;
56 | -webkit-transition: all 300ms cubic-bezier(0,1.92,.99,1.07);
57 | transition: all 300ms cubic-bezier(0,1.92,.99,1.07);
58 | -webkit-transform: translate3d(0, -10px, 0);
59 | transform: translate3d(0, -10px, 0);
60 | }
61 |
62 | core-tooltip.fancy:hover::shadow .core-tooltip,
63 | core-tooltip.fancy:focus::shadow .core-tooltip {
64 | opacity: 1;
65 | -webkit-transform: translate3d(0, 0, 0);
66 | transform: translate3d(0, 0, 0);
67 | }
68 |
69 | .sample-show-hide {
70 |
71 | }
72 |
73 | .sample-show-hide {
74 | -webkit-transition:all linear 0.5s;
75 | transition:all linear 0.5s;
76 | }
77 |
78 | .sample-show-hide.ng-hide {
79 | opacity:0;
80 | }
81 |
82 |
83 | .md-subheader {
84 | background-color: #dcedc8;
85 |
86 | }
87 | h2.md-subheader {
88 | margin: 0px;
89 | margin-left: -24px;
90 | margin-right: -24px;
91 | margin-top: -24px; }
92 | h2.md-subheader.md-sticky-clone {
93 | margin-right: 0px;
94 | margin-top: 0px;
95 | box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.16); }
96 | h2 .md-subheader-content {
97 | padding-left: 10px; }
98 |
99 |
100 |
101 | md-backdrop {
102 | position: fixed !important;
103 | }
104 |
105 | md-toast {
106 | position: fixed !important;
107 |
108 | }
109 |
110 | md-sidenav {
111 | position: fixed !important;
112 | }
113 |
114 | md-tooltip {
115 | position: fixed !important;
116 | }
117 |
118 | .menu-item {
119 | background: none;
120 | border-width: 0;
121 | cursor: pointer;
122 | display: block;
123 | color: #333;
124 | font-size: inherit;
125 | line-height: 40px;
126 | max-height: 40px;
127 | opacity: 1;
128 | margin: 0;
129 | outline: none;
130 | padding: 0px 28px;
131 | position: relative;
132 | text-align: left;
133 | text-decoration: none;
134 | width: 100%;
135 | z-index: 1;
136 | -webkit-transition: 0.45s cubic-bezier(0.35, 0, 0.25, 1);
137 | -webkit-transition-property: max-height, background-color, opacity;
138 | -moz-transition: 0.45s cubic-bezier(0.35, 0, 0.25, 1);
139 | -moz-transition-property: max-height, background-color, opacity;
140 | transition: 0.45s cubic-bezier(0.35, 0, 0.25, 1);
141 | transition-property: max-height, background-color, opacity;
142 | }
143 | .menu-item.ng-hide {
144 | max-height: 0;
145 | opacity: 0;
146 | }
147 | .menu-item:hover {
148 | color: #999;
149 | }
150 | .menu-item:focus {
151 | font-weight: bold;
152 | }
153 | .menu-item.menu-title {
154 | color: #888;
155 | font-size: 14px;
156 | padding-left: 16px;
157 | text-align: left;
158 | text-transform: uppercase;
159 | transition: color 0.35s cubic-bezier(0.35, 0, 0.25, 1);
160 | }
161 | .menu-item.menu-title:hover,
162 | .menu-item.menu-title.active {
163 | color: #1976d2;
164 | }
165 |
166 | .menu-icon {
167 | background: none;
168 | border: none;
169 | }
170 |
171 | .menu-separator-icon {
172 | margin: 0;
173 | }
174 | .menu-module-name {
175 | opacity: 0.6;
176 | font-size: 18px;
177 | }
178 |
179 | .list-cont {
180 | background-color: #E7E7E7 !important;
181 | max-width: 800px;
182 | margin: 0 auto;
183 | height: 100%;
184 | overflow: hidden;
185 | }
186 |
187 | .list-cb {
188 | margin: 0;
189 | position: relative;
190 | top: 15px;
191 | left: 19px;
192 | }
193 |
194 | .list-check-area {
195 | width:56px;
196 | height: 56px;
197 | padding:0;
198 | margin-right: 10px;
199 | }
--------------------------------------------------------------------------------
/app/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Declare app level module which depends on views, and components
4 | angular.module('myApp', [
5 | 'ngRoute',
6 | 'myApp.view1',
7 | 'myApp.home',
8 | 'myApp.version',
9 | 'ngMaterial'
10 | ]).
11 | config(['$routeProvider', function($routeProvider) {
12 | $routeProvider.otherwise({redirectTo: '/home'});
13 | }])
14 |
15 | .controller('MainCtrl', function($scope, $timeout, $mdSidenav) {
16 | $scope.toggleRight = function() {
17 | $mdSidenav('left').toggle();
18 | };
19 |
20 | $scope.menu = {};
21 | $scope.menu.pages = [
22 | {"url": "/home", "discription":"Главная"},
23 | {"url": "/view1", "discription":"Список дел"}
24 |
25 | ];
26 |
27 | $scope.menu.isPageSelected = function(page) {
28 | return ($scope.menu.currentPage === page);
29 | };
30 |
31 | $scope.menu.toggleSelectPage = function(page) {
32 | $scope.menu.currentPage = page;
33 | };
34 | })
35 |
36 | .controller('LeftCtrl', function($scope, $timeout, $mdSidenav) {
37 | $scope.close = function() {
38 | $mdSidenav('left').close();
39 | };
40 | });
--------------------------------------------------------------------------------
/app/components/version/interpolate-filter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.version.interpolate-filter', [])
4 |
5 | .filter('interpolate', ['version', function(version) {
6 | return function(text) {
7 | return String(text).replace(/\%VERSION\%/mg, version);
8 | };
9 | }]);
10 |
--------------------------------------------------------------------------------
/app/components/version/interpolate-filter_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('myApp.version module', function() {
4 | beforeEach(module('myApp.version'));
5 |
6 | describe('interpolate filter', function() {
7 | beforeEach(module(function($provide) {
8 | $provide.value('version', 'TEST_VER');
9 | }));
10 |
11 | it('should replace VERSION', inject(function(interpolateFilter) {
12 | expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after');
13 | }));
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/app/components/version/version-directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.version.version-directive', [])
4 |
5 | .directive('appVersion', ['version', function(version) {
6 | return function(scope, elm, attrs) {
7 | elm.text(version);
8 | };
9 | }]);
10 |
--------------------------------------------------------------------------------
/app/components/version/version-directive_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('myApp.version module', function() {
4 | beforeEach(module('myApp.version'));
5 |
6 | describe('app-version directive', function() {
7 | it('should print current version', function() {
8 | module(function($provide) {
9 | $provide.value('version', 'TEST_VER');
10 | });
11 | inject(function($compile, $rootScope) {
12 | var element = $compile('')($rootScope);
13 | expect(element.text()).toEqual('TEST_VER');
14 | });
15 | });
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/app/components/version/version.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.version', [
4 | 'myApp.version.interpolate-filter',
5 | 'myApp.version.version-directive'
6 | ])
7 |
8 | .value('version', '0.1');
9 |
--------------------------------------------------------------------------------
/app/components/version/version_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('myApp.version module', function() {
4 | beforeEach(module('myApp.version'));
5 |
6 | describe('version service', function() {
7 | it('should return current version', inject(function(version) {
8 | expect(version).toEqual('0.1');
9 | }));
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/app/dialog.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Добавить
6 |
7 |
43 |
44 |
45 |
46 |
47 |
48 | Отмена
49 |
50 |
51 | Добавить
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/home/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Это простая демонстрация разработки Angular приложения в стиле Material Design с библиотеки Material Angular
4 |
Внимание!: В данном приложении не содержится никакой серверной части, поэтому все изменения не будут сохраняться.
5 |
Приложение служит только для демонстрации
6 |
Переходите в 'Список дел', там Вы можете добавлять, удалять задачи, можете выбирать несколько задач сразу
7 |
8 |
--------------------------------------------------------------------------------
/app/home/home.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.home', ['ngRoute','ngMaterial'])
4 |
5 | .config(['$routeProvider', function($routeProvider) {
6 | $routeProvider.when('/home', {
7 | templateUrl: 'home/home.html',
8 | controller: 'HomeCtrl'
9 | });
10 | }])
11 |
12 | .controller('HomeCtrl', function($scope) {
13 |
14 | });
--------------------------------------------------------------------------------
/app/img/icons/ic_add_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
24 |
--------------------------------------------------------------------------------
/app/img/icons/ic_close_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
24 |
--------------------------------------------------------------------------------
/app/img/icons/ic_done_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
26 |
--------------------------------------------------------------------------------
/app/img/icons/ic_done_all_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
--------------------------------------------------------------------------------
/app/img/icons/ic_menu_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
24 |
--------------------------------------------------------------------------------
/app/img/icons/ic_refresh_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | TODO list
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
49 | Список задач
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/app/view1/view1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
40 |
41 |
42 |
{{item.what}}
43 |
{{item.who}}
44 |
45 | {{item.notes}}
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | В архив
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Добавить
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/app/view1/view1.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.view1', ['ngRoute','ngMaterial'])
4 |
5 | .config(['$routeProvider', function($routeProvider) {
6 | $routeProvider.when('/view1', {
7 | templateUrl: 'view1/view1.html',
8 | controller: 'View1Ctrl'
9 | });
10 | }])
11 |
12 | .controller('View1Ctrl', function($scope, $mdDialog, $mdToast, $animate) {
13 |
14 | $scope.todos = [
15 | {
16 | color: {
17 | red: 125,
18 | green: 5,
19 | blue: 50
20 | },
21 | what: 'Brunch this weekend?',
22 | when: '3:08PM',
23 | notes: " I'll be in your neighborhood doing errands",
24 | check: false,
25 | show: false,
26 | visible: true, // для анимации удаления
27 | btns: false
28 | },
29 | {
30 | color: {
31 | red: 125,
32 | green: 225,
33 | blue: 0
34 | },
35 | what: 'Brunch this weekend?',
36 | when: '3:08PM',
37 | notes: " I'll be in your neighborhood doing errands",
38 | check: false,
39 | show: false,
40 | visible: true,
41 | btns: false
42 | },
43 | {
44 | color: {
45 | red: 25,
46 | green: 15,
47 | blue: 50
48 | },
49 | what: 'Brunch this weekend?',
50 | when: '3:08PM',
51 | notes: " I'll be in your neighborhood doing errands",
52 | check: false,
53 | show: false,
54 | visible: true,
55 | btns: false
56 | },
57 | {
58 | color: {
59 | red: 125,
60 | green: 5,
61 | blue: 150
62 | },
63 | what: 'Brunch this weekend?',
64 | when: '3:08PM',
65 | notes: " I'll be in your neighborhood doing errands",
66 | check: false,
67 | show: false,
68 | visible: true,
69 | btns: false
70 | },
71 | {
72 | color: {
73 | red: 25,
74 | green: 5,
75 | blue: 150
76 | },
77 | what: 'Brunch this weekend?',
78 | when: '3:08PM',
79 | notes: " I'll be in your neighborhood doing errands",
80 | check: false,
81 | show: false,
82 | visible: true,
83 | btns: false
84 | },
85 | ]
86 |
87 |
88 | $scope.showItem = function(item ) {
89 | item.show = true;
90 | };
91 |
92 | $scope.hideItem = function(item ) {
93 | item.show = false;
94 | };
95 |
96 | $scope.countSelected = 0;
97 | $scope.oneSelected= false;
98 |
99 | $scope.deselectAll = function(item) {
100 |
101 | $scope.todos.forEach( function(element) {
102 |
103 | decheck(element);
104 | });
105 |
106 | if($scope.countSelected>0) {
107 | $scope.oneSelected = true;
108 | } else {
109 | $scope.oneSelected = false;
110 | }
111 | }
112 |
113 | $scope.remove = function(item) {
114 | item.visible = false;
115 | var idx = $scope.todos.indexOf(item);
116 |
117 |
118 |
119 | setTimeout( function() {
120 | $scope.todos.splice(idx,1);
121 |
122 | $mdToast.show(
123 | $mdToast.simple()
124 | .content('Запись отправлена в архив')
125 | .position($scope.getToastPosition())
126 | .hideDelay(3000)
127 | );
128 |
129 |
130 | $scope.countSelected = 0;
131 | } ,1000);
132 |
133 | };
134 |
135 | $scope.toastPosition = {
136 | bottom: true,
137 | top: false,
138 | left: true,
139 | right: false
140 | };
141 |
142 | $scope.getToastPosition = function() {
143 | return Object.keys($scope.toastPosition)
144 | .filter(function(pos) { return $scope.toastPosition[pos]; })
145 | .join(' ');
146 | };
147 |
148 | $scope.archiveAll = function () {
149 |
150 | //Здесь должен выполняться запросс на удаление
151 | var newTodos = [];
152 | $scope.todos.forEach(function(item){
153 | if(item.check ===false){
154 |
155 | } else {
156 | item.visible = false;
157 | }
158 | });
159 |
160 |
161 | setTimeout( function() {
162 | $scope.todos.forEach(function(item){
163 | if(item.check ===false){
164 | newTodos.push(item);
165 | }
166 | });
167 |
168 |
169 | $scope.todos = newTodos;
170 |
171 |
172 | $mdToast.show(
173 | $mdToast.simple()
174 | .content('Отправленно в архив записей: ' + $scope.countSelected)
175 | .position($scope.getToastPosition())
176 | .hideDelay(3000)
177 | );
178 |
179 |
180 | $scope.countSelected = 0;
181 |
182 | } ,1000);
183 |
184 | $scope.oneSelected = false;
185 |
186 | }
187 |
188 | function decheck(item) {
189 | if(item.check===true) {
190 | $scope.countSelected--;
191 | }
192 |
193 | item.check=false;
194 | }
195 |
196 | $scope.oneCheck = function(item) {
197 |
198 |
199 | if(item.check===true) {
200 | $scope.countSelected++;
201 | } else {
202 | $scope.countSelected--;
203 | }
204 |
205 | if($scope.countSelected>0) {
206 | $scope.oneSelected = true;
207 | } else {
208 | $scope.oneSelected = false;
209 | }
210 | };
211 |
212 | $scope.showAlert = function(ev) {
213 |
214 | $mdDialog.show({
215 | controller: DialogController,
216 | templateUrl: 'dialog.tmpl.html',
217 | targetEvent: ev,
218 | })
219 | .then(function(answer) {
220 |
221 |
222 | var item = {
223 |
224 | color: answer.color,
225 | what: answer.what,
226 | when: answer.when,
227 | notes: answer.notes,
228 | check: false,
229 | show: false,
230 | visible: true
231 | };
232 |
233 | $scope.todos.unshift(item);
234 |
235 |
236 | $mdToast.show(
237 | $mdToast.simple()
238 | .content('Задание добавлено')
239 | .position($scope.getToastPosition())
240 | .hideDelay(3000)
241 | );
242 |
243 | }, function() {
244 | /* 'You cancelled the dialog.';*/
245 | });
246 | };
247 |
248 | });
249 |
250 | function DialogController($scope, $mdDialog) {
251 |
252 | $scope.todo = {};
253 |
254 | $scope.todo.color = {
255 | red: Math.floor(Math.random() * 255),
256 | green: Math.floor(Math.random() * 255),
257 | blue: Math.floor(Math.random() * 255)
258 | };
259 |
260 | $scope.hide = function() {
261 | $mdDialog.hide();
262 | };
263 | $scope.cancel = function() {
264 | $mdDialog.cancel();
265 | };
266 | $scope.answer = function(answer) {
267 | $mdDialog.hide(answer);
268 | };
269 | }
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "material angular demo",
3 | "description": "Material angular demo project",
4 | "version": "0.0.0",
5 | "homepage": "https://github.com/nesterione/material-angular-demo-project",
6 | "private": true,
7 | "dependencies": {
8 | "angular": "1.3.x",
9 | "angular-route": "1.3.x",
10 | "angular-loader": "1.3.x",
11 | "angular-mocks": "~1.3.x",
12 | "html5-boilerplate": "~4.3.0",
13 | "angular-material":""
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/dist/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nesterione/material-angular-demo-project/e252a895166858fdcffb1f0269d90d457120ceb7/dist/.gitkeep
--------------------------------------------------------------------------------
/dist/app.css:
--------------------------------------------------------------------------------
1 | /* app css stylesheet */
2 | body {
3 | height: none;
4 | background-color: #E7E7E7;
5 | }
6 |
7 | .box {
8 | width: 200px;
9 | height: 200px;
10 | background-color: yellow;
11 |
12 | }
13 |
14 | .fix-top {
15 | position: fixed;
16 | top:0;
17 | }
18 |
19 | .nornal-btn {
20 | width: 56px;
21 | height: 56px;
22 | }
23 |
24 | .nornal-round-btn {
25 | width: 56px;
26 | height: 56px;
27 | border-radius: 50%;
28 | }
29 |
30 | .float-btn {
31 | height:56px;
32 | width: 56px;
33 | position: fixed;
34 | bottom: 55px;
35 | right: 55px;
36 | }
37 |
38 | md-whiteframe {
39 | background: #fff;
40 | margin: 20px;
41 | padding: 20px;
42 | }
43 |
44 | .check {
45 | background-color: #E8EAF6;
46 | }
47 | .left-box {
48 | width:56px; height: 56px; padding:0; background-color: gray; border-radius: 50%;
49 | }
50 | .active-checkbox {
51 | background-color: transparent !important;
52 | }
53 |
54 | core-tooltip.fancy::shadow .core-tooltip {
55 | opacity: 0;
56 | -webkit-transition: all 300ms cubic-bezier(0,1.92,.99,1.07);
57 | transition: all 300ms cubic-bezier(0,1.92,.99,1.07);
58 | -webkit-transform: translate3d(0, -10px, 0);
59 | transform: translate3d(0, -10px, 0);
60 | }
61 |
62 | core-tooltip.fancy:hover::shadow .core-tooltip,
63 | core-tooltip.fancy:focus::shadow .core-tooltip {
64 | opacity: 1;
65 | -webkit-transform: translate3d(0, 0, 0);
66 | transform: translate3d(0, 0, 0);
67 | }
68 |
69 | .sample-show-hide {
70 |
71 | }
72 |
73 | .sample-show-hide {
74 | -webkit-transition:all linear 0.5s;
75 | transition:all linear 0.5s;
76 | }
77 |
78 | .sample-show-hide.ng-hide {
79 | opacity:0;
80 | }
81 |
82 |
83 | .md-subheader {
84 | background-color: #dcedc8;
85 |
86 | }
87 | h2.md-subheader {
88 | margin: 0px;
89 | margin-left: -24px;
90 | margin-right: -24px;
91 | margin-top: -24px; }
92 | h2.md-subheader.md-sticky-clone {
93 | margin-right: 0px;
94 | margin-top: 0px;
95 | box-shadow: 0px 2px 4px 0 rgba(0, 0, 0, 0.16); }
96 | h2 .md-subheader-content {
97 | padding-left: 10px; }
98 |
99 |
100 |
101 | md-backdrop {
102 | position: fixed !important;
103 | }
104 |
105 | md-toast {
106 | position: fixed !important;
107 |
108 | }
109 |
110 | md-sidenav {
111 | position: fixed !important;
112 | }
113 |
114 | md-tooltip {
115 | position: fixed !important;
116 | }
117 |
118 | .menu-item {
119 | background: none;
120 | border-width: 0;
121 | cursor: pointer;
122 | display: block;
123 | color: #333;
124 | font-size: inherit;
125 | line-height: 40px;
126 | max-height: 40px;
127 | opacity: 1;
128 | margin: 0;
129 | outline: none;
130 | padding: 0px 28px;
131 | position: relative;
132 | text-align: left;
133 | text-decoration: none;
134 | width: 100%;
135 | z-index: 1;
136 | -webkit-transition: 0.45s cubic-bezier(0.35, 0, 0.25, 1);
137 | -webkit-transition-property: max-height, background-color, opacity;
138 | -moz-transition: 0.45s cubic-bezier(0.35, 0, 0.25, 1);
139 | -moz-transition-property: max-height, background-color, opacity;
140 | transition: 0.45s cubic-bezier(0.35, 0, 0.25, 1);
141 | transition-property: max-height, background-color, opacity;
142 | }
143 | .menu-item.ng-hide {
144 | max-height: 0;
145 | opacity: 0;
146 | }
147 | .menu-item:hover {
148 | color: #999;
149 | }
150 | .menu-item:focus {
151 | font-weight: bold;
152 | }
153 | .menu-item.menu-title {
154 | color: #888;
155 | font-size: 14px;
156 | padding-left: 16px;
157 | text-align: left;
158 | text-transform: uppercase;
159 | transition: color 0.35s cubic-bezier(0.35, 0, 0.25, 1);
160 | }
161 | .menu-item.menu-title:hover,
162 | .menu-item.menu-title.active {
163 | color: #1976d2;
164 | }
165 |
166 | .menu-icon {
167 | background: none;
168 | border: none;
169 | }
170 |
171 | .menu-separator-icon {
172 | margin: 0;
173 | }
174 | .menu-module-name {
175 | opacity: 0.6;
176 | font-size: 18px;
177 | }
178 |
179 | .list-cont {
180 | background-color: #E7E7E7 !important;
181 | max-width: 800px;
182 | margin: 0 auto;
183 | height: 100%;
184 | overflow: hidden;
185 | }
186 |
187 | .list-cb {
188 | margin: 0;
189 | position: relative;
190 | top: 15px;
191 | left: 19px;
192 | }
193 |
194 | .list-check-area {
195 | width:56px;
196 | height: 56px;
197 | padding:0;
198 | margin-right: 10px;
199 | }
--------------------------------------------------------------------------------
/dist/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Declare app level module which depends on views, and components
4 | angular.module('myApp', [
5 | 'ngRoute',
6 | 'myApp.view1',
7 | 'myApp.home',
8 | 'myApp.version',
9 | 'ngMaterial'
10 | ]).
11 | config(['$routeProvider', function($routeProvider) {
12 | $routeProvider.otherwise({redirectTo: '/home'});
13 | }])
14 |
15 | .controller('MainCtrl', function($scope, $timeout, $mdSidenav) {
16 | $scope.toggleRight = function() {
17 | $mdSidenav('left').toggle();
18 | };
19 |
20 | $scope.menu = {};
21 | $scope.menu.pages = [
22 | {"url": "/home", "discription":"Главная"},
23 | {"url": "/view1", "discription":"Список дел"}
24 |
25 | ];
26 |
27 | $scope.menu.isPageSelected = function(page) {
28 | return ($scope.menu.currentPage === page);
29 | };
30 |
31 | $scope.menu.toggleSelectPage = function(page) {
32 | $scope.menu.currentPage = page;
33 | };
34 | })
35 |
36 | .controller('LeftCtrl', function($scope, $timeout, $mdSidenav) {
37 | $scope.close = function() {
38 | $mdSidenav('left').close();
39 | };
40 | });
--------------------------------------------------------------------------------
/dist/components/version/interpolate-filter.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.version.interpolate-filter', [])
4 |
5 | .filter('interpolate', ['version', function(version) {
6 | return function(text) {
7 | return String(text).replace(/\%VERSION\%/mg, version);
8 | };
9 | }]);
10 |
--------------------------------------------------------------------------------
/dist/components/version/interpolate-filter_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('myApp.version module', function() {
4 | beforeEach(module('myApp.version'));
5 |
6 | describe('interpolate filter', function() {
7 | beforeEach(module(function($provide) {
8 | $provide.value('version', 'TEST_VER');
9 | }));
10 |
11 | it('should replace VERSION', inject(function(interpolateFilter) {
12 | expect(interpolateFilter('before %VERSION% after')).toEqual('before TEST_VER after');
13 | }));
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/dist/components/version/version-directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.version.version-directive', [])
4 |
5 | .directive('appVersion', ['version', function(version) {
6 | return function(scope, elm, attrs) {
7 | elm.text(version);
8 | };
9 | }]);
10 |
--------------------------------------------------------------------------------
/dist/components/version/version-directive_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('myApp.version module', function() {
4 | beforeEach(module('myApp.version'));
5 |
6 | describe('app-version directive', function() {
7 | it('should print current version', function() {
8 | module(function($provide) {
9 | $provide.value('version', 'TEST_VER');
10 | });
11 | inject(function($compile, $rootScope) {
12 | var element = $compile('')($rootScope);
13 | expect(element.text()).toEqual('TEST_VER');
14 | });
15 | });
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/dist/components/version/version.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.version', [
4 | 'myApp.version.interpolate-filter',
5 | 'myApp.version.version-directive'
6 | ])
7 |
8 | .value('version', '0.1');
9 |
--------------------------------------------------------------------------------
/dist/components/version/version_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('myApp.version module', function() {
4 | beforeEach(module('myApp.version'));
5 |
6 | describe('version service', function() {
7 | it('should return current version', inject(function(version) {
8 | expect(version).toEqual('0.1');
9 | }));
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/dist/dialog.tmpl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Добавить
6 |
7 |
43 |
44 |
45 |
46 |
47 |
48 | Отмена
49 |
50 |
51 | Добавить
52 |
53 |
54 |
--------------------------------------------------------------------------------
/dist/home/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
Это простая демонстрация разработки Angular приложения в стиле Material Design с библиотеки Material Angular
4 |
Внимание!: В данном приложении не содержится никакой серверной части, поэтому все изменения не будут сохраняться.
5 |
Приложение служит только для демонстрации
6 |
Переходите в 'Список дел', там Вы можете добавлять, удалять задачи, можете выбирать несколько задач сразу
7 |
8 |
--------------------------------------------------------------------------------
/dist/home/home.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.home', ['ngRoute','ngMaterial'])
4 |
5 | .config(['$routeProvider', function($routeProvider) {
6 | $routeProvider.when('/home', {
7 | templateUrl: 'home/home.html',
8 | controller: 'HomeCtrl'
9 | });
10 | }])
11 |
12 | .controller('HomeCtrl', function($scope) {
13 |
14 | });
--------------------------------------------------------------------------------
/dist/img/icons/ic_add_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
24 |
--------------------------------------------------------------------------------
/dist/img/icons/ic_close_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
24 |
--------------------------------------------------------------------------------
/dist/img/icons/ic_done_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
26 |
--------------------------------------------------------------------------------
/dist/img/icons/ic_done_all_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
--------------------------------------------------------------------------------
/dist/img/icons/ic_menu_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
24 |
--------------------------------------------------------------------------------
/dist/img/icons/ic_refresh_24px.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
25 |
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | TODO list
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
49 | Список задач
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
65 |
66 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/dist/view1/view1.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
40 |
41 |
42 |
{{item.what}}
43 |
{{item.who}}
44 |
45 | {{item.notes}}
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | В архив
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Добавить
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/dist/view1/view1.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.view1', ['ngRoute','ngMaterial'])
4 |
5 | .config(['$routeProvider', function($routeProvider) {
6 | $routeProvider.when('/view1', {
7 | templateUrl: 'view1/view1.html',
8 | controller: 'View1Ctrl'
9 | });
10 | }])
11 |
12 | .controller('View1Ctrl', function($scope, $mdDialog, $mdToast, $animate) {
13 |
14 | $scope.todos = [
15 | {
16 | color: {
17 | red: 125,
18 | green: 5,
19 | blue: 50
20 | },
21 | what: 'Brunch this weekend?',
22 | when: '3:08PM',
23 | notes: " I'll be in your neighborhood doing errands",
24 | check: false,
25 | show: false,
26 | visible: true, // для анимации удаления
27 | btns: false
28 | },
29 | {
30 | color: {
31 | red: 125,
32 | green: 225,
33 | blue: 0
34 | },
35 | what: 'Brunch this weekend?',
36 | when: '3:08PM',
37 | notes: " I'll be in your neighborhood doing errands",
38 | check: false,
39 | show: false,
40 | visible: true,
41 | btns: false
42 | },
43 | {
44 | color: {
45 | red: 25,
46 | green: 15,
47 | blue: 50
48 | },
49 | what: 'Brunch this weekend?',
50 | when: '3:08PM',
51 | notes: " I'll be in your neighborhood doing errands",
52 | check: false,
53 | show: false,
54 | visible: true,
55 | btns: false
56 | },
57 | {
58 | color: {
59 | red: 125,
60 | green: 5,
61 | blue: 150
62 | },
63 | what: 'Brunch this weekend?',
64 | when: '3:08PM',
65 | notes: " I'll be in your neighborhood doing errands",
66 | check: false,
67 | show: false,
68 | visible: true,
69 | btns: false
70 | },
71 | {
72 | color: {
73 | red: 25,
74 | green: 5,
75 | blue: 150
76 | },
77 | what: 'Brunch this weekend?',
78 | when: '3:08PM',
79 | notes: " I'll be in your neighborhood doing errands",
80 | check: false,
81 | show: false,
82 | visible: true,
83 | btns: false
84 | },
85 | ]
86 |
87 |
88 | $scope.showItem = function(item ) {
89 | item.show = true;
90 | };
91 |
92 | $scope.hideItem = function(item ) {
93 | item.show = false;
94 | };
95 |
96 | $scope.countSelected = 0;
97 | $scope.oneSelected= false;
98 |
99 | $scope.deselectAll = function(item) {
100 |
101 | $scope.todos.forEach( function(element) {
102 |
103 | decheck(element);
104 | });
105 |
106 | if($scope.countSelected>0) {
107 | $scope.oneSelected = true;
108 | } else {
109 | $scope.oneSelected = false;
110 | }
111 | }
112 |
113 | $scope.remove = function(item) {
114 | item.visible = false;
115 | var idx = $scope.todos.indexOf(item);
116 |
117 |
118 |
119 | setTimeout( function() {
120 | $scope.todos.splice(idx,1);
121 |
122 | $mdToast.show(
123 | $mdToast.simple()
124 | .content('Запись отправлена в архив')
125 | .position($scope.getToastPosition())
126 | .hideDelay(3000)
127 | );
128 |
129 |
130 | $scope.countSelected = 0;
131 | } ,1000);
132 |
133 | };
134 |
135 | $scope.toastPosition = {
136 | bottom: true,
137 | top: false,
138 | left: true,
139 | right: false
140 | };
141 |
142 | $scope.getToastPosition = function() {
143 | return Object.keys($scope.toastPosition)
144 | .filter(function(pos) { return $scope.toastPosition[pos]; })
145 | .join(' ');
146 | };
147 |
148 | $scope.archiveAll = function () {
149 |
150 | //Здесь должен выполняться запросс на удаление
151 | var newTodos = [];
152 | $scope.todos.forEach(function(item){
153 | if(item.check ===false){
154 |
155 | } else {
156 | item.visible = false;
157 | }
158 | });
159 |
160 |
161 | setTimeout( function() {
162 | $scope.todos.forEach(function(item){
163 | if(item.check ===false){
164 | newTodos.push(item);
165 | }
166 | });
167 |
168 |
169 | $scope.todos = newTodos;
170 |
171 |
172 | $mdToast.show(
173 | $mdToast.simple()
174 | .content('Отправленно в архив записей: ' + $scope.countSelected)
175 | .position($scope.getToastPosition())
176 | .hideDelay(3000)
177 | );
178 |
179 |
180 | $scope.countSelected = 0;
181 |
182 | } ,1000);
183 |
184 | $scope.oneSelected = false;
185 |
186 | }
187 |
188 | function decheck(item) {
189 | if(item.check===true) {
190 | $scope.countSelected--;
191 | }
192 |
193 | item.check=false;
194 | }
195 |
196 | $scope.oneCheck = function(item) {
197 |
198 |
199 | if(item.check===true) {
200 | $scope.countSelected++;
201 | } else {
202 | $scope.countSelected--;
203 | }
204 |
205 | if($scope.countSelected>0) {
206 | $scope.oneSelected = true;
207 | } else {
208 | $scope.oneSelected = false;
209 | }
210 | };
211 |
212 | $scope.showAlert = function(ev) {
213 |
214 | $mdDialog.show({
215 | controller: DialogController,
216 | templateUrl: 'dialog.tmpl.html',
217 | targetEvent: ev,
218 | })
219 | .then(function(answer) {
220 |
221 |
222 | var item = {
223 |
224 | color: answer.color,
225 | what: answer.what,
226 | when: answer.when,
227 | notes: answer.notes,
228 | check: false,
229 | show: false,
230 | visible: true
231 | };
232 |
233 | $scope.todos.unshift(item);
234 |
235 |
236 | $mdToast.show(
237 | $mdToast.simple()
238 | .content('Задание добавлено')
239 | .position($scope.getToastPosition())
240 | .hideDelay(3000)
241 | );
242 |
243 | }, function() {
244 | /* 'You cancelled the dialog.';*/
245 | });
246 | };
247 |
248 | });
249 |
250 | function DialogController($scope, $mdDialog) {
251 |
252 | $scope.todo = {};
253 |
254 | $scope.todo.color = {
255 | red: Math.floor(Math.random() * 255),
256 | green: Math.floor(Math.random() * 255),
257 | blue: Math.floor(Math.random() * 255)
258 | };
259 |
260 | $scope.hide = function() {
261 | $mdDialog.hide();
262 | };
263 | $scope.cancel = function() {
264 | $mdDialog.cancel();
265 | };
266 | $scope.answer = function(answer) {
267 | $mdDialog.hide(answer);
268 | };
269 | }
--------------------------------------------------------------------------------
/dist/view1/view1_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('myApp.view1 module', function() {
4 |
5 | beforeEach(module('myApp.view1'));
6 |
7 | describe('view1 controller', function(){
8 |
9 | it('should ....', inject(function($controller) {
10 | //spec body
11 | var view1Ctrl = $controller('View1Ctrl');
12 | expect(view1Ctrl).toBeDefined();
13 | }));
14 |
15 | });
16 | });
--------------------------------------------------------------------------------
/dist/view2/view2.html:
--------------------------------------------------------------------------------
1 |
2 |
Toast can be dismissed with a swipe, a timer, or a button.
3 |
4 |
5 |
6 | Show Custom
7 |
8 |
9 | Show Simple
10 |
11 |
12 | Show With Action
13 |
14 |
15 |
16 |
17 |
18 | Toast Position: "{{getToastPosition()}}"
19 |
20 |
21 | {{name}}
22 |
23 |
24 | FAB
25 |
26 |
27 | FAB
28 |
29 |
30 |
--------------------------------------------------------------------------------
/dist/view2/view2.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('myApp.view2', ['ngRoute','ngMaterial'])
4 |
5 | .config(['$routeProvider', function($routeProvider) {
6 | $routeProvider.when('/view2', {
7 | templateUrl: 'view2/view2.html',
8 | controller: 'View2Ctrl'
9 | });
10 | }])
11 |
12 | .controller('View2Ctrl', function($scope, $mdToast, $animate) {
13 | $scope.toastPosition = {
14 | bottom: false,
15 | top: true,
16 | left: false,
17 | right: true
18 | };
19 | $scope.getToastPosition = function() {
20 | return Object.keys($scope.toastPosition)
21 | .filter(function(pos) { return $scope.toastPosition[pos]; })
22 | .join(' ');
23 | };
24 | $scope.showCustomToast = function() {
25 | $mdToast.show({
26 | controller: 'ToastCtrl',
27 | templateUrl: 'toast-template.html',
28 | hideDelay: 6000,
29 | position: $scope.getToastPosition()
30 | });
31 | };
32 | $scope.showSimpleToast = function() {
33 | $mdToast.show(
34 | $mdToast.simple()
35 | .content('Simple Toast!')
36 | .position($scope.getToastPosition())
37 | .hideDelay(0)
38 | );
39 | };
40 | $scope.showActionToast = function() {
41 | var toast = $mdToast.simple()
42 | .content('Action Toast!')
43 | .action('OK')
44 | .highlightAction(false)
45 | .position($scope.getToastPosition());
46 | $mdToast.show(toast).then(function() {
47 | alert('You clicked \'OK\'.');
48 | });
49 | };
50 | })
51 | .controller('ToastCtrl', function($scope, $mdToast) {
52 | $scope.closeToast = function() {
53 | $mdToast.hide();
54 | };
55 | });
--------------------------------------------------------------------------------
/dist/view2/view2_test.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | describe('myApp.view2 module', function() {
4 |
5 | beforeEach(module('myApp.view2'));
6 |
7 | describe('view2 controller', function(){
8 |
9 | it('should ....', inject(function($controller) {
10 | //spec body
11 | var view2Ctrl = $controller('View2Ctrl');
12 | expect(view2Ctrl).toBeDefined();
13 | }));
14 |
15 | });
16 | });
--------------------------------------------------------------------------------
/e2e-tests/protractor.conf.js:
--------------------------------------------------------------------------------
1 | exports.config = {
2 | allScriptsTimeout: 11000,
3 |
4 | specs: [
5 | '*.js'
6 | ],
7 |
8 | capabilities: {
9 | 'browserName': 'chrome'
10 | },
11 |
12 | baseUrl: 'http://localhost:8000/app/',
13 |
14 | framework: 'jasmine',
15 |
16 | jasmineNodeOpts: {
17 | defaultTimeoutInterval: 30000
18 | }
19 | };
20 |
--------------------------------------------------------------------------------
/e2e-tests/scenarios.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /* https://github.com/angular/protractor/blob/master/docs/toc.md */
4 |
5 | describe('my app', function() {
6 |
7 | browser.get('index.html');
8 |
9 | it('should automatically redirect to /view1 when location hash/fragment is empty', function() {
10 | expect(browser.getLocationAbsUrl()).toMatch("/view1");
11 | });
12 |
13 |
14 | describe('view1', function() {
15 |
16 | beforeEach(function() {
17 | browser.get('index.html#/view1');
18 | });
19 |
20 |
21 | it('should render view1 when user navigates to /view1', function() {
22 | expect(element.all(by.css('[ng-view] p')).first().getText()).
23 | toMatch(/partial for view 1/);
24 | });
25 |
26 | });
27 |
28 |
29 | describe('view2', function() {
30 |
31 | beforeEach(function() {
32 | browser.get('index.html#/view2');
33 | });
34 |
35 |
36 | it('should render view2 when user navigates to /view2', function() {
37 | expect(element.all(by.css('[ng-view] p')).first().getText()).
38 | toMatch(/partial for view 2/);
39 | });
40 |
41 | });
42 | });
43 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function(config){
2 | config.set({
3 |
4 | basePath : './',
5 |
6 | files : [
7 | 'app/bower_components/angular/angular.js',
8 | 'app/bower_components/angular-route/angular-route.js',
9 | 'app/bower_components/angular-mocks/angular-mocks.js',
10 | 'app/components/**/*.js',
11 | 'app/view*/**/*.js'
12 | ],
13 |
14 | autoWatch : true,
15 |
16 | frameworks: ['jasmine'],
17 |
18 | browsers : ['Chrome'],
19 |
20 | plugins : [
21 | 'karma-chrome-launcher',
22 | 'karma-firefox-launcher',
23 | 'karma-jasmine',
24 | 'karma-junit-reporter'
25 | ],
26 |
27 | junitReporter : {
28 | outputFile: 'test_out/unit.xml',
29 | suite: 'unit'
30 | }
31 |
32 | });
33 | };
34 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "material-angular-demo-project",
3 | "private": true,
4 | "version": "0.0.0",
5 | "description": "Material angular demo project",
6 | "repository": "https://github.com/nesterione/material-angular-demo-project",
7 | "devDependencies": {
8 | "karma": "~0.10",
9 | "protractor": "^1.1.1",
10 | "http-server": "^0.6.1",
11 | "bower": "^1.3.1",
12 | "shelljs": "^0.2.6",
13 | "karma-junit-reporter": "^0.2.2"
14 | },
15 | "scripts": {
16 | "postinstall": "bower install",
17 |
18 | "prestart": "npm install",
19 | "start": "http-server -a localhost -p 8888 -c-1",
20 |
21 | "pretest": "npm install",
22 | "test": "karma start karma.conf.js",
23 | "test-single-run": "karma start karma.conf.js --single-run",
24 |
25 | "preupdate-webdriver": "npm install",
26 | "update-webdriver": "webdriver-manager update",
27 |
28 | "preprotractor": "npm run update-webdriver",
29 | "protractor": "protractor e2e-tests/protractor.conf.js",
30 |
31 | "update-index-async": "node -e \"require('shelljs/global'); sed('-i', /\\/\\/@@NG_LOADER_START@@[\\s\\S]*\\/\\/@@NG_LOADER_END@@/, '//@@NG_LOADER_START@@\\n' + sed(/sourceMappingURL=angular-loader.min.js.map/,'sourceMappingURL=bower_components/angular-loader/angular-loader.min.js.map','app/bower_components/angular-loader/angular-loader.min.js') + '\\n//@@NG_LOADER_END@@', 'app/index-async.html');\""
32 | }
33 | }
34 |
--------------------------------------------------------------------------------