mirror of
				https://github.com/richard-loafle/fuse-angular.git
				synced 2025-11-04 00:53:34 +00:00 
			
		
		
		
	Merge branch 'master' of https://github.com/withinpixels/fuse2
This commit is contained in:
		
						commit
						786180958d
					
				
							
								
								
									
										918
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										918
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -1299,7 +1299,6 @@
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "anymatch": "1.3.0",
 | 
			
		||||
        "async-each": "1.0.1",
 | 
			
		||||
        "fsevents": "1.1.2",
 | 
			
		||||
        "glob-parent": "2.0.0",
 | 
			
		||||
        "inherits": "2.0.3",
 | 
			
		||||
        "is-binary-path": "1.0.1",
 | 
			
		||||
@ -3443,905 +3442,6 @@
 | 
			
		||||
      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "fsevents": {
 | 
			
		||||
      "version": "1.1.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz",
 | 
			
		||||
      "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "optional": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "nan": "2.6.2",
 | 
			
		||||
        "node-pre-gyp": "0.6.36"
 | 
			
		||||
      },
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "abbrev": {
 | 
			
		||||
          "version": "1.1.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "ajv": {
 | 
			
		||||
          "version": "4.11.8",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "co": "4.6.0",
 | 
			
		||||
            "json-stable-stringify": "1.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "ansi-regex": {
 | 
			
		||||
          "version": "2.1.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "aproba": {
 | 
			
		||||
          "version": "1.1.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "are-we-there-yet": {
 | 
			
		||||
          "version": "1.1.4",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "delegates": "1.0.0",
 | 
			
		||||
            "readable-stream": "2.2.9"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "asn1": {
 | 
			
		||||
          "version": "0.2.3",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "assert-plus": {
 | 
			
		||||
          "version": "0.2.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "asynckit": {
 | 
			
		||||
          "version": "0.4.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "aws-sign2": {
 | 
			
		||||
          "version": "0.6.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "aws4": {
 | 
			
		||||
          "version": "1.6.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "balanced-match": {
 | 
			
		||||
          "version": "0.4.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "bcrypt-pbkdf": {
 | 
			
		||||
          "version": "1.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "tweetnacl": "0.14.5"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "block-stream": {
 | 
			
		||||
          "version": "0.0.9",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "inherits": "2.0.3"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "boom": {
 | 
			
		||||
          "version": "2.10.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "hoek": "2.16.3"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "brace-expansion": {
 | 
			
		||||
          "version": "1.1.7",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "balanced-match": "0.4.2",
 | 
			
		||||
            "concat-map": "0.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "buffer-shims": {
 | 
			
		||||
          "version": "1.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "caseless": {
 | 
			
		||||
          "version": "0.12.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "co": {
 | 
			
		||||
          "version": "4.6.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "code-point-at": {
 | 
			
		||||
          "version": "1.1.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "combined-stream": {
 | 
			
		||||
          "version": "1.0.5",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "delayed-stream": "1.0.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "concat-map": {
 | 
			
		||||
          "version": "0.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "console-control-strings": {
 | 
			
		||||
          "version": "1.1.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "core-util-is": {
 | 
			
		||||
          "version": "1.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "cryptiles": {
 | 
			
		||||
          "version": "2.0.5",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "boom": "2.10.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "dashdash": {
 | 
			
		||||
          "version": "1.14.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "assert-plus": "1.0.0"
 | 
			
		||||
          },
 | 
			
		||||
          "dependencies": {
 | 
			
		||||
            "assert-plus": {
 | 
			
		||||
              "version": "1.0.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "debug": {
 | 
			
		||||
          "version": "2.6.8",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "ms": "2.0.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "deep-extend": {
 | 
			
		||||
          "version": "0.4.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "delayed-stream": {
 | 
			
		||||
          "version": "1.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "delegates": {
 | 
			
		||||
          "version": "1.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "ecc-jsbn": {
 | 
			
		||||
          "version": "0.1.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "jsbn": "0.1.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "extend": {
 | 
			
		||||
          "version": "3.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "extsprintf": {
 | 
			
		||||
          "version": "1.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "forever-agent": {
 | 
			
		||||
          "version": "0.6.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "form-data": {
 | 
			
		||||
          "version": "2.1.4",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "asynckit": "0.4.0",
 | 
			
		||||
            "combined-stream": "1.0.5",
 | 
			
		||||
            "mime-types": "2.1.15"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "fs.realpath": {
 | 
			
		||||
          "version": "1.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "fstream": {
 | 
			
		||||
          "version": "1.0.11",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "graceful-fs": "4.1.11",
 | 
			
		||||
            "inherits": "2.0.3",
 | 
			
		||||
            "mkdirp": "0.5.1",
 | 
			
		||||
            "rimraf": "2.6.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "fstream-ignore": {
 | 
			
		||||
          "version": "1.0.5",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "fstream": "1.0.11",
 | 
			
		||||
            "inherits": "2.0.3",
 | 
			
		||||
            "minimatch": "3.0.4"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "gauge": {
 | 
			
		||||
          "version": "2.7.4",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "aproba": "1.1.1",
 | 
			
		||||
            "console-control-strings": "1.1.0",
 | 
			
		||||
            "has-unicode": "2.0.1",
 | 
			
		||||
            "object-assign": "4.1.1",
 | 
			
		||||
            "signal-exit": "3.0.2",
 | 
			
		||||
            "string-width": "1.0.2",
 | 
			
		||||
            "strip-ansi": "3.0.1",
 | 
			
		||||
            "wide-align": "1.1.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "getpass": {
 | 
			
		||||
          "version": "0.1.7",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "assert-plus": "1.0.0"
 | 
			
		||||
          },
 | 
			
		||||
          "dependencies": {
 | 
			
		||||
            "assert-plus": {
 | 
			
		||||
              "version": "1.0.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "glob": {
 | 
			
		||||
          "version": "7.1.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "fs.realpath": "1.0.0",
 | 
			
		||||
            "inflight": "1.0.6",
 | 
			
		||||
            "inherits": "2.0.3",
 | 
			
		||||
            "minimatch": "3.0.4",
 | 
			
		||||
            "once": "1.4.0",
 | 
			
		||||
            "path-is-absolute": "1.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "graceful-fs": {
 | 
			
		||||
          "version": "4.1.11",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "har-schema": {
 | 
			
		||||
          "version": "1.0.5",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "har-validator": {
 | 
			
		||||
          "version": "4.2.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "ajv": "4.11.8",
 | 
			
		||||
            "har-schema": "1.0.5"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "has-unicode": {
 | 
			
		||||
          "version": "2.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "hawk": {
 | 
			
		||||
          "version": "3.1.3",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "boom": "2.10.1",
 | 
			
		||||
            "cryptiles": "2.0.5",
 | 
			
		||||
            "hoek": "2.16.3",
 | 
			
		||||
            "sntp": "1.0.9"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "hoek": {
 | 
			
		||||
          "version": "2.16.3",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "http-signature": {
 | 
			
		||||
          "version": "1.1.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "assert-plus": "0.2.0",
 | 
			
		||||
            "jsprim": "1.4.0",
 | 
			
		||||
            "sshpk": "1.13.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "inflight": {
 | 
			
		||||
          "version": "1.0.6",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "once": "1.4.0",
 | 
			
		||||
            "wrappy": "1.0.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "inherits": {
 | 
			
		||||
          "version": "2.0.3",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "ini": {
 | 
			
		||||
          "version": "1.3.4",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "is-fullwidth-code-point": {
 | 
			
		||||
          "version": "1.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "number-is-nan": "1.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "is-typedarray": {
 | 
			
		||||
          "version": "1.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "isarray": {
 | 
			
		||||
          "version": "1.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "isstream": {
 | 
			
		||||
          "version": "0.1.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "jodid25519": {
 | 
			
		||||
          "version": "1.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "jsbn": "0.1.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "jsbn": {
 | 
			
		||||
          "version": "0.1.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "json-schema": {
 | 
			
		||||
          "version": "0.2.3",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "json-stable-stringify": {
 | 
			
		||||
          "version": "1.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "jsonify": "0.0.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "json-stringify-safe": {
 | 
			
		||||
          "version": "5.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "jsonify": {
 | 
			
		||||
          "version": "0.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "jsprim": {
 | 
			
		||||
          "version": "1.4.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "assert-plus": "1.0.0",
 | 
			
		||||
            "extsprintf": "1.0.2",
 | 
			
		||||
            "json-schema": "0.2.3",
 | 
			
		||||
            "verror": "1.3.6"
 | 
			
		||||
          },
 | 
			
		||||
          "dependencies": {
 | 
			
		||||
            "assert-plus": {
 | 
			
		||||
              "version": "1.0.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "mime-db": {
 | 
			
		||||
          "version": "1.27.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "mime-types": {
 | 
			
		||||
          "version": "2.1.15",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "mime-db": "1.27.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "minimatch": {
 | 
			
		||||
          "version": "3.0.4",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "brace-expansion": "1.1.7"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "minimist": {
 | 
			
		||||
          "version": "0.0.8",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "mkdirp": {
 | 
			
		||||
          "version": "0.5.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "minimist": "0.0.8"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "ms": {
 | 
			
		||||
          "version": "2.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "node-pre-gyp": {
 | 
			
		||||
          "version": "0.6.36",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "mkdirp": "0.5.1",
 | 
			
		||||
            "nopt": "4.0.1",
 | 
			
		||||
            "npmlog": "4.1.0",
 | 
			
		||||
            "rc": "1.2.1",
 | 
			
		||||
            "request": "2.81.0",
 | 
			
		||||
            "rimraf": "2.6.1",
 | 
			
		||||
            "semver": "5.3.0",
 | 
			
		||||
            "tar": "2.2.1",
 | 
			
		||||
            "tar-pack": "3.4.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "nopt": {
 | 
			
		||||
          "version": "4.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "abbrev": "1.1.0",
 | 
			
		||||
            "osenv": "0.1.4"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "npmlog": {
 | 
			
		||||
          "version": "4.1.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "are-we-there-yet": "1.1.4",
 | 
			
		||||
            "console-control-strings": "1.1.0",
 | 
			
		||||
            "gauge": "2.7.4",
 | 
			
		||||
            "set-blocking": "2.0.0"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "number-is-nan": {
 | 
			
		||||
          "version": "1.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "oauth-sign": {
 | 
			
		||||
          "version": "0.8.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "object-assign": {
 | 
			
		||||
          "version": "4.1.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "once": {
 | 
			
		||||
          "version": "1.4.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "wrappy": "1.0.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "os-homedir": {
 | 
			
		||||
          "version": "1.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "os-tmpdir": {
 | 
			
		||||
          "version": "1.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "osenv": {
 | 
			
		||||
          "version": "0.1.4",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "os-homedir": "1.0.2",
 | 
			
		||||
            "os-tmpdir": "1.0.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "path-is-absolute": {
 | 
			
		||||
          "version": "1.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "performance-now": {
 | 
			
		||||
          "version": "0.2.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "process-nextick-args": {
 | 
			
		||||
          "version": "1.0.7",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "punycode": {
 | 
			
		||||
          "version": "1.4.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "qs": {
 | 
			
		||||
          "version": "6.4.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "rc": {
 | 
			
		||||
          "version": "1.2.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "deep-extend": "0.4.2",
 | 
			
		||||
            "ini": "1.3.4",
 | 
			
		||||
            "minimist": "1.2.0",
 | 
			
		||||
            "strip-json-comments": "2.0.1"
 | 
			
		||||
          },
 | 
			
		||||
          "dependencies": {
 | 
			
		||||
            "minimist": {
 | 
			
		||||
              "version": "1.2.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "readable-stream": {
 | 
			
		||||
          "version": "2.2.9",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "buffer-shims": "1.0.0",
 | 
			
		||||
            "core-util-is": "1.0.2",
 | 
			
		||||
            "inherits": "2.0.3",
 | 
			
		||||
            "isarray": "1.0.0",
 | 
			
		||||
            "process-nextick-args": "1.0.7",
 | 
			
		||||
            "string_decoder": "1.0.1",
 | 
			
		||||
            "util-deprecate": "1.0.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "request": {
 | 
			
		||||
          "version": "2.81.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "aws-sign2": "0.6.0",
 | 
			
		||||
            "aws4": "1.6.0",
 | 
			
		||||
            "caseless": "0.12.0",
 | 
			
		||||
            "combined-stream": "1.0.5",
 | 
			
		||||
            "extend": "3.0.1",
 | 
			
		||||
            "forever-agent": "0.6.1",
 | 
			
		||||
            "form-data": "2.1.4",
 | 
			
		||||
            "har-validator": "4.2.1",
 | 
			
		||||
            "hawk": "3.1.3",
 | 
			
		||||
            "http-signature": "1.1.1",
 | 
			
		||||
            "is-typedarray": "1.0.0",
 | 
			
		||||
            "isstream": "0.1.2",
 | 
			
		||||
            "json-stringify-safe": "5.0.1",
 | 
			
		||||
            "mime-types": "2.1.15",
 | 
			
		||||
            "oauth-sign": "0.8.2",
 | 
			
		||||
            "performance-now": "0.2.0",
 | 
			
		||||
            "qs": "6.4.0",
 | 
			
		||||
            "safe-buffer": "5.0.1",
 | 
			
		||||
            "stringstream": "0.0.5",
 | 
			
		||||
            "tough-cookie": "2.3.2",
 | 
			
		||||
            "tunnel-agent": "0.6.0",
 | 
			
		||||
            "uuid": "3.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "rimraf": {
 | 
			
		||||
          "version": "2.6.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "glob": "7.1.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "safe-buffer": {
 | 
			
		||||
          "version": "5.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "semver": {
 | 
			
		||||
          "version": "5.3.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "set-blocking": {
 | 
			
		||||
          "version": "2.0.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "signal-exit": {
 | 
			
		||||
          "version": "3.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "sntp": {
 | 
			
		||||
          "version": "1.0.9",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "hoek": "2.16.3"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "sshpk": {
 | 
			
		||||
          "version": "1.13.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "asn1": "0.2.3",
 | 
			
		||||
            "assert-plus": "1.0.0",
 | 
			
		||||
            "bcrypt-pbkdf": "1.0.1",
 | 
			
		||||
            "dashdash": "1.14.1",
 | 
			
		||||
            "ecc-jsbn": "0.1.1",
 | 
			
		||||
            "getpass": "0.1.7",
 | 
			
		||||
            "jodid25519": "1.0.2",
 | 
			
		||||
            "jsbn": "0.1.1",
 | 
			
		||||
            "tweetnacl": "0.14.5"
 | 
			
		||||
          },
 | 
			
		||||
          "dependencies": {
 | 
			
		||||
            "assert-plus": {
 | 
			
		||||
              "version": "1.0.0",
 | 
			
		||||
              "bundled": true,
 | 
			
		||||
              "dev": true,
 | 
			
		||||
              "optional": true
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "string-width": {
 | 
			
		||||
          "version": "1.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "code-point-at": "1.1.0",
 | 
			
		||||
            "is-fullwidth-code-point": "1.0.0",
 | 
			
		||||
            "strip-ansi": "3.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "string_decoder": {
 | 
			
		||||
          "version": "1.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "safe-buffer": "5.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "stringstream": {
 | 
			
		||||
          "version": "0.0.5",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "strip-ansi": {
 | 
			
		||||
          "version": "3.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "ansi-regex": "2.1.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "strip-json-comments": {
 | 
			
		||||
          "version": "2.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "tar": {
 | 
			
		||||
          "version": "2.2.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "block-stream": "0.0.9",
 | 
			
		||||
            "fstream": "1.0.11",
 | 
			
		||||
            "inherits": "2.0.3"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "tar-pack": {
 | 
			
		||||
          "version": "3.4.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "debug": "2.6.8",
 | 
			
		||||
            "fstream": "1.0.11",
 | 
			
		||||
            "fstream-ignore": "1.0.5",
 | 
			
		||||
            "once": "1.4.0",
 | 
			
		||||
            "readable-stream": "2.2.9",
 | 
			
		||||
            "rimraf": "2.6.1",
 | 
			
		||||
            "tar": "2.2.1",
 | 
			
		||||
            "uid-number": "0.0.6"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "tough-cookie": {
 | 
			
		||||
          "version": "2.3.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "punycode": "1.4.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "tunnel-agent": {
 | 
			
		||||
          "version": "0.6.0",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "safe-buffer": "5.0.1"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "tweetnacl": {
 | 
			
		||||
          "version": "0.14.5",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "uid-number": {
 | 
			
		||||
          "version": "0.0.6",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "util-deprecate": {
 | 
			
		||||
          "version": "1.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        },
 | 
			
		||||
        "uuid": {
 | 
			
		||||
          "version": "3.0.1",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true
 | 
			
		||||
        },
 | 
			
		||||
        "verror": {
 | 
			
		||||
          "version": "1.3.6",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "extsprintf": "1.0.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "wide-align": {
 | 
			
		||||
          "version": "1.1.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true,
 | 
			
		||||
          "optional": true,
 | 
			
		||||
          "requires": {
 | 
			
		||||
            "string-width": "1.0.2"
 | 
			
		||||
          }
 | 
			
		||||
        },
 | 
			
		||||
        "wrappy": {
 | 
			
		||||
          "version": "1.0.2",
 | 
			
		||||
          "bundled": true,
 | 
			
		||||
          "dev": true
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "fstream": {
 | 
			
		||||
      "version": "1.0.11",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
 | 
			
		||||
@ -8940,6 +8040,15 @@
 | 
			
		||||
      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "string_decoder": {
 | 
			
		||||
      "version": "1.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "safe-buffer": "5.1.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "string-width": {
 | 
			
		||||
      "version": "2.1.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
 | 
			
		||||
@ -8967,15 +8076,6 @@
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "string_decoder": {
 | 
			
		||||
      "version": "1.0.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
 | 
			
		||||
      "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "requires": {
 | 
			
		||||
        "safe-buffer": "5.1.1"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "stringstream": {
 | 
			
		||||
      "version": "0.0.5",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
 | 
			
		||||
 | 
			
		||||
@ -36,6 +36,10 @@ const appRoutes: Routes = [
 | 
			
		||||
        path        : 'apps/calendar',
 | 
			
		||||
        loadChildren: './main/content/apps/calendar/calendar.module#FuseCalendarModule'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path        : 'apps/e-commerce',
 | 
			
		||||
        loadChildren: './main/content/apps/e-commerce/e-commerce.module#FuseEcommerceModule'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path        : 'apps/todo',
 | 
			
		||||
        loadChildren: './main/content/apps/todo/todo.module#FuseTodoModule'
 | 
			
		||||
 | 
			
		||||
@ -82,10 +82,12 @@ export class FuseUtils
 | 
			
		||||
    {
 | 
			
		||||
        function S4()
 | 
			
		||||
        {
 | 
			
		||||
            return (((1 + Math.random()) * 0x10000) || 0).toString(16).substring(1);
 | 
			
		||||
            return Math.floor((1 + Math.random()) * 0x10000)
 | 
			
		||||
                       .toString(16)
 | 
			
		||||
                       .substring(1);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return (S4() + S4());
 | 
			
		||||
        return S4() + S4();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static toggleInArray(item, array)
 | 
			
		||||
@ -99,4 +101,14 @@ export class FuseUtils
 | 
			
		||||
            array.splice(array.indexOf(item), 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static handleize(text)
 | 
			
		||||
    {
 | 
			
		||||
        return text.toString().toLowerCase()
 | 
			
		||||
                   .replace(/\s+/g, '-')           // Replace spaces with -
 | 
			
		||||
                   .replace(/[^\w\-]+/g, '')       // Remove all non-word chars
 | 
			
		||||
                   .replace(/\-\-+/g, '-')         // Replace multiple - with single -
 | 
			
		||||
                   .replace(/^-+/, '')             // Trim - from start of text
 | 
			
		||||
                   .replace(/-+$/, '');            // Trim - from end of text
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -187,6 +187,11 @@ $matColorHues: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, A100, A200, A400
 | 
			
		||||
        // Generate material element colors
 | 
			
		||||
        // based on current contrast color
 | 
			
		||||
        @include generateMaterialElementColors($contrastColor);
 | 
			
		||||
 | 
			
		||||
        &[disabled] {
 | 
			
		||||
            background-color: rgba($color, .12) !important;
 | 
			
		||||
            color: rgba($contrastColor, .26) !important;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .#{$colorName}#{$hue}-fg {
 | 
			
		||||
 | 
			
		||||
@ -96,7 +96,7 @@ $top-bg-image: url('assets/images/backgrounds/header-bg.png');
 | 
			
		||||
                        max-height: $carded-toolbar-height;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    .content {
 | 
			
		||||
                    > .content {
 | 
			
		||||
                        display: flex;
 | 
			
		||||
                        flex: 1;
 | 
			
		||||
                        overflow: auto;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3962
									
								
								src/app/fuse-fake-db/e-commerce.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3962
									
								
								src/app/fuse-fake-db/e-commerce.ts
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -15,6 +15,7 @@ import { ProjectsDashboardDb } from './projects-dashboard';
 | 
			
		||||
import { ScrumboardFakeDb } from './scrumboard';
 | 
			
		||||
import { FaqFakeDb } from './faq';
 | 
			
		||||
import { KnowledgeBaseFakeDb } from './knowledge-base';
 | 
			
		||||
import { ECommerceFakeDb } from './e-commerce';
 | 
			
		||||
 | 
			
		||||
export class FuseFakeDbService implements InMemoryDbService
 | 
			
		||||
{
 | 
			
		||||
@ -48,7 +49,10 @@ export class FuseFakeDbService implements InMemoryDbService
 | 
			
		||||
            'projects-dashboard-widgets' : ProjectsDashboardDb.widgets,
 | 
			
		||||
            'scrumboard-boards'          : ScrumboardFakeDb.boards,
 | 
			
		||||
            'faq'                        : FaqFakeDb.data,
 | 
			
		||||
            'knowledge-base'             : KnowledgeBaseFakeDb.data
 | 
			
		||||
            'knowledge-base'             : KnowledgeBaseFakeDb.data,
 | 
			
		||||
            'e-commerce-dashboard'       : ECommerceFakeDb.dashboard,
 | 
			
		||||
            'e-commerce-products'        : ECommerceFakeDb.products,
 | 
			
		||||
            'e-commerce-orders'        : ECommerceFakeDb.orders
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,325 @@
 | 
			
		||||
<div id="e-commerce-dashboard" class="page-layout simple fullwidth">
 | 
			
		||||
 | 
			
		||||
    <!-- CONTENT -->
 | 
			
		||||
    <div class="content p-24 w-100-p">
 | 
			
		||||
 | 
			
		||||
        <!-- WIDGET GROUP -->
 | 
			
		||||
        <div class="widget-group" fxLayout="row" fxFlex="100" fxLayoutWrap fxLayoutAlign="start start" *fuseIfOnDom [@animateStagger]="{value:'50'}">
 | 
			
		||||
 | 
			
		||||
            <!-- WIDGET 1 -->
 | 
			
		||||
            <fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
 | 
			
		||||
 | 
			
		||||
                <!-- Front -->
 | 
			
		||||
                <div class="fuse-widget-front mat-white-bg mat-elevation-z2">
 | 
			
		||||
                    <div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
 | 
			
		||||
                        <mat-form-field>
 | 
			
		||||
                            <mat-select class="simplified font-size-16" [(ngModel)]="widgets.widget1.currentRange"
 | 
			
		||||
                                        aria-label="Change range">
 | 
			
		||||
                                <mat-option *ngFor="let range of widgets.widget1.ranges | keys"
 | 
			
		||||
                                            [value]="range.key">
 | 
			
		||||
                                    {{range.value}}
 | 
			
		||||
                                </mat-option>
 | 
			
		||||
                            </mat-select>
 | 
			
		||||
                        </mat-form-field>
 | 
			
		||||
                        <button mat-icon-button fuseWidgetToggle aria-label="more">
 | 
			
		||||
                            <mat-icon>more_vert</mat-icon>
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
 | 
			
		||||
                        <div class="light-blue-fg font-size-72 line-height-72">
 | 
			
		||||
                            {{widgets.widget1.data.count[widgets.widget1.currentRange]}}
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="h3 secondary-text font-weight-500">{{widgets.widget1.data.label}}</div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                        <span class="h4 secondary-text text-truncate">{{widgets.widget1.data.extra.label}}:</span>
 | 
			
		||||
                        <span class="h4 ml-8">{{widgets.widget1.data.extra.count[widgets.widget1.currentRange]}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Front -->
 | 
			
		||||
 | 
			
		||||
                <!-- Back -->
 | 
			
		||||
                <div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
 | 
			
		||||
                    <button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
 | 
			
		||||
                            aria-label="Flip widget">
 | 
			
		||||
                        <mat-icon class="s-16">close</mat-icon>
 | 
			
		||||
                    </button>
 | 
			
		||||
 | 
			
		||||
                    <div>
 | 
			
		||||
                        {{widgets.widget1.detail}}
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Back -->
 | 
			
		||||
 | 
			
		||||
            </fuse-widget>
 | 
			
		||||
            <!-- / WIDGET 1 -->
 | 
			
		||||
 | 
			
		||||
            <!-- WIDGET 2 -->
 | 
			
		||||
            <fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
 | 
			
		||||
 | 
			
		||||
                <!-- Front -->
 | 
			
		||||
                <div class="fuse-widget-front mat-white-bg mat-elevation-z2">
 | 
			
		||||
                    <div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
 | 
			
		||||
                        <div class="h3">{{widgets.widget2.title}}</div>
 | 
			
		||||
 | 
			
		||||
                        <button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
 | 
			
		||||
                            <mat-icon>more_vert</mat-icon>
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
 | 
			
		||||
                        <div class="red-fg font-size-72 line-height-72">
 | 
			
		||||
                            {{widgets.widget2.data.count}}
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="h3 secondary-text font-weight-500">{{widgets.widget2.data.label}}</div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                        <span class="h4 secondary-text text-truncate">{{widgets.widget2.data.extra.label}}:</span>
 | 
			
		||||
                        <span class="h4 ml-8">{{widgets.widget2.data.extra.count}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Front -->
 | 
			
		||||
 | 
			
		||||
                <!-- Back -->
 | 
			
		||||
                <div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
 | 
			
		||||
                    <button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
 | 
			
		||||
                            aria-label="Flip widget">
 | 
			
		||||
                        <mat-icon class="s-16">close</mat-icon>
 | 
			
		||||
                    </button>
 | 
			
		||||
 | 
			
		||||
                    <div>
 | 
			
		||||
                        {{widgets.widget2.detail}}
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Back -->
 | 
			
		||||
 | 
			
		||||
            </fuse-widget>
 | 
			
		||||
            <!-- / WIDGET 2 -->
 | 
			
		||||
 | 
			
		||||
            <!-- WIDGET 3 -->
 | 
			
		||||
            <fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
 | 
			
		||||
 | 
			
		||||
                <!-- Front -->
 | 
			
		||||
                <div class="fuse-widget-front mat-white-bg mat-elevation-z2">
 | 
			
		||||
                    <div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
 | 
			
		||||
                        <div class="h3">{{widgets.widget3.title}}</div>
 | 
			
		||||
 | 
			
		||||
                        <button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
 | 
			
		||||
                            <mat-icon>more_vert</mat-icon>
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
 | 
			
		||||
                        <div class="orange-fg font-size-72 line-height-72">
 | 
			
		||||
                            {{widgets.widget3.data.count}}
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="h3 secondary-text font-weight-500">{{widgets.widget3.data.label}}</div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                        <span class="h4 secondary-text text-truncate">{{widgets.widget3.data.extra.label}}:</span>
 | 
			
		||||
                        <span class="h4 ml-8">{{widgets.widget3.data.extra.count}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Front -->
 | 
			
		||||
 | 
			
		||||
                <!-- Back -->
 | 
			
		||||
                <div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
 | 
			
		||||
                    <button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
 | 
			
		||||
                            aria-label="Flip widget">
 | 
			
		||||
                        <mat-icon class="s-16">close</mat-icon>
 | 
			
		||||
                    </button>
 | 
			
		||||
 | 
			
		||||
                    <div>
 | 
			
		||||
                        {{widgets.widget3.detail}}
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Back -->
 | 
			
		||||
 | 
			
		||||
            </fuse-widget>
 | 
			
		||||
            <!-- / WIDGET 3 -->
 | 
			
		||||
 | 
			
		||||
            <!-- WIDGET 4 -->
 | 
			
		||||
            <fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-xs="50" fxFlex.gt-md="25">
 | 
			
		||||
 | 
			
		||||
                <!-- Front -->
 | 
			
		||||
                <div class="fuse-widget-front mat-white-bg mat-elevation-z2">
 | 
			
		||||
                    <div class="pl-16 pr-8 py-16 h-52" fxLayout="row" fxLayoutAlign="space-between center">
 | 
			
		||||
                        <div class="h3">{{widgets.widget4.title}}</div>
 | 
			
		||||
 | 
			
		||||
                        <button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button" aria-label="more">
 | 
			
		||||
                            <mat-icon>more_vert</mat-icon>
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="pt-8 pb-32" fxLayout="column" fxLayoutAlign="center center">
 | 
			
		||||
                        <div class="blue-grey-fg font-size-72 line-height-72">{{widgets.widget4.data.count}}
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="h3 secondary-text font-weight-500">{{widgets.widget4.data.label}}</div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="p-16 grey-50-bg border-top" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                        <span class="h4 secondary-text text-truncate">{{widgets.widget4.data.extra.label}}:</span>
 | 
			
		||||
                        <span class="h4 ml-8">{{widgets.widget4.data.extra.count}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Front -->
 | 
			
		||||
 | 
			
		||||
                <!-- Back -->
 | 
			
		||||
                <div class="fuse-widget-back p-16 pt-32 mat-white-bg mat-elevation-z2">
 | 
			
		||||
                    <button mat-icon-button fuseWidgetToggle class="fuse-widget-flip-button"
 | 
			
		||||
                            aria-label="Flip widget">
 | 
			
		||||
                        <mat-icon class="s-16">close</mat-icon>
 | 
			
		||||
                    </button>
 | 
			
		||||
 | 
			
		||||
                    <div>
 | 
			
		||||
                        {{widgets.widget4.detail}}
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Back -->
 | 
			
		||||
 | 
			
		||||
            </fuse-widget>
 | 
			
		||||
            <!-- / WIDGET 4 -->
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            <!-- WIDGET 5 -->
 | 
			
		||||
            <fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="row" fxFlex="100">
 | 
			
		||||
 | 
			
		||||
                <!-- Front -->
 | 
			
		||||
                <div class="fuse-widget-front mat-white-bg mat-elevation-z2">
 | 
			
		||||
 | 
			
		||||
                    <div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center" fxLayoutWrap>
 | 
			
		||||
 | 
			
		||||
                        <div fxFlex class="py-8 h3">{{widgets.widget5.title}}</div>
 | 
			
		||||
 | 
			
		||||
                        <div fxFlex="0 1 auto" class="py-8" fxLayout="row">
 | 
			
		||||
                            <button mat-button class="px-16"
 | 
			
		||||
                                    *ngFor="let range of widgets.widget5.ranges | keys"
 | 
			
		||||
                                    (click)="widget5.currentRange = range.key"
 | 
			
		||||
                                    [disabled]="widget5.currentRange == range.key">
 | 
			
		||||
                                {{range.value}}
 | 
			
		||||
                            </button>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="h-420">
 | 
			
		||||
                        <ngx-charts-bar-vertical-stacked
 | 
			
		||||
                            *fuseIfOnDom
 | 
			
		||||
                            [scheme]="widget5.scheme"
 | 
			
		||||
                            [results]="this.widgets.widget5.mainChart[this.widget5.currentRange]"
 | 
			
		||||
                            [gradient]="widget5.gradient"
 | 
			
		||||
                            [xAxis]="widget5.xAxis"
 | 
			
		||||
                            [yAxis]="widget5.yAxis"
 | 
			
		||||
                            [legend]="widget5.legend"
 | 
			
		||||
                            [showXAxisLabel]="widget5.showXAxisLabel"
 | 
			
		||||
                            [showYAxisLabel]="widget5.showYAxisLabel"
 | 
			
		||||
                            [xAxisLabel]="widget5.xAxisLabel"
 | 
			
		||||
                            [yAxisLabel]="widget5.yAxisLabel"
 | 
			
		||||
                            (select)="widget5.onSelect($event)">
 | 
			
		||||
                        </ngx-charts-bar-vertical-stacked>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Front -->
 | 
			
		||||
 | 
			
		||||
            </fuse-widget>
 | 
			
		||||
            <!-- / WIDGET 5 -->
 | 
			
		||||
 | 
			
		||||
            <!-- WIDGET 6 -->
 | 
			
		||||
            <fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
 | 
			
		||||
 | 
			
		||||
                <!-- Front -->
 | 
			
		||||
                <div class="fuse-widget-front mat-white-bg mat-elevation-z2">
 | 
			
		||||
 | 
			
		||||
                    <div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
 | 
			
		||||
                        <div class="h3">{{widgets.widget6.title}}</div>
 | 
			
		||||
                        <mat-form-field>
 | 
			
		||||
                            <mat-select class="simplified" [(ngModel)]="widget6.currentRange" aria-label="Change range">
 | 
			
		||||
                                <mat-option *ngFor="let range of widgets.widget6.ranges | keys"
 | 
			
		||||
                                            [value]="range.key">
 | 
			
		||||
                                    {{range.value}}
 | 
			
		||||
                                </mat-option>
 | 
			
		||||
                            </mat-select>
 | 
			
		||||
                        </mat-form-field>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="h-400">
 | 
			
		||||
                        <ngx-charts-pie-chart
 | 
			
		||||
                            *fuseIfOnDom
 | 
			
		||||
                            [scheme]="widget6.scheme"
 | 
			
		||||
                            [results]="widgets.widget6.mainChart[widget6.currentRange]"
 | 
			
		||||
                            [legend]="widget6.showLegend"
 | 
			
		||||
                            [explodeSlices]="widget6.explodeSlices"
 | 
			
		||||
                            [labels]="widget6.labels"
 | 
			
		||||
                            [doughnut]="widget6.doughnut"
 | 
			
		||||
                            [gradient]="widget6.gradient"
 | 
			
		||||
                            (select)="widget6.onSelect($event)">
 | 
			
		||||
                        </ngx-charts-pie-chart>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="py-8 mh-16 border-top" fxLayout="row" fxLayoutAlign="start center" fxLayoutWrap>
 | 
			
		||||
                        <div class="py-8 border-right" fxLayout="column" fxLayoutAlign="center center" fxFlex="100" fxFlex.gt-sm="50">
 | 
			
		||||
                            <span class="mat-display-1 mb-0">{{widgets.widget6.footerLeft.count[widget6.currentRange]}}</span>
 | 
			
		||||
                            <span class="h4">{{widgets.widget6.footerLeft.title}}</span>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <div class="py-8" fxLayout="column" fxLayoutAlign="center center" fxFlex="100" fxFlex.gt-sm="50">
 | 
			
		||||
                            <span class="mat-display-1 mb-0">{{widgets.widget6.footerRight.count[widget6.currentRange]}}</span>
 | 
			
		||||
                            <span class="h4">{{widgets.widget6.footerRight.title}}</span>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Front -->
 | 
			
		||||
 | 
			
		||||
            </fuse-widget>
 | 
			
		||||
            <!-- / WIDGET 6 -->
 | 
			
		||||
 | 
			
		||||
            <!-- WIDGET 7 -->
 | 
			
		||||
            <fuse-widget [@animate]="{value:'*',params:{y:'100%'}}" class="widget" fxLayout="column" fxFlex="100" fxFlex.gt-sm="50">
 | 
			
		||||
 | 
			
		||||
                <!-- Front -->
 | 
			
		||||
                <div class="fuse-widget-front mat-white-bg mat-elevation-z2">
 | 
			
		||||
 | 
			
		||||
                    <div class="px-16 border-bottom" fxLayout="row" fxLayoutAlign="space-between center">
 | 
			
		||||
                        <div class="h3">{{widgets.widget7.title}}</div>
 | 
			
		||||
                        <mat-form-field>
 | 
			
		||||
                            <mat-select class="simplified" [(ngModel)]="widget7.currentRange"
 | 
			
		||||
                                        aria-label="Change range">
 | 
			
		||||
                                <mat-option *ngFor="let range of widgets.widget7.ranges | keys"
 | 
			
		||||
                                            [value]="range.key">
 | 
			
		||||
                                    {{range.value}}
 | 
			
		||||
                                </mat-option>
 | 
			
		||||
                            </mat-select>
 | 
			
		||||
                        </mat-form-field>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    <div class="p-16" fxLayout="row" fxLayoutAlign="space-between center"
 | 
			
		||||
                         *ngFor="let customer of widgets.widget7.customers[widget7.currentRange]">
 | 
			
		||||
                        <div>
 | 
			
		||||
                            <div class="h3">{{customer.name}}</div>
 | 
			
		||||
                            <div>
 | 
			
		||||
                                <span *ngIf="customer.location">{{customer.location}}</span>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
                        <button mat-icon-button aria-label="More information">
 | 
			
		||||
                            <mat-icon>more_vert</mat-icon>
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
                <!-- / Front -->
 | 
			
		||||
 | 
			
		||||
            </fuse-widget>
 | 
			
		||||
            <!-- / WIDGET 7 -->
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / WIDGET GROUP -->
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- / CONTENT -->
 | 
			
		||||
 | 
			
		||||
</div>
 | 
			
		||||
@ -0,0 +1,7 @@
 | 
			
		||||
#e-commerce-dashboard {
 | 
			
		||||
 | 
			
		||||
    .content {
 | 
			
		||||
        flex: 1 0 auto;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,93 @@
 | 
			
		||||
import { Component, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
 | 
			
		||||
import { EcommerceDashboardService } from './dashboard.service';
 | 
			
		||||
import * as shape from 'd3-shape';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 | 
			
		||||
import { Observable } from 'rxjs/Observable';
 | 
			
		||||
import { DataSource } from '@angular/cdk/collections';
 | 
			
		||||
import { fuseAnimations } from '../../../../../core/animations';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector     : 'fuse-e-commerce-dashboard',
 | 
			
		||||
    templateUrl  : './dashboard.component.html',
 | 
			
		||||
    styleUrls    : ['./dashboard.component.scss'],
 | 
			
		||||
    encapsulation: ViewEncapsulation.None,
 | 
			
		||||
    animations   : fuseAnimations
 | 
			
		||||
})
 | 
			
		||||
export class FuseEcommerceDashboardComponent implements OnInit, OnDestroy
 | 
			
		||||
{
 | 
			
		||||
    projects: any[];
 | 
			
		||||
    selectedProject: any;
 | 
			
		||||
 | 
			
		||||
    widgets: any;
 | 
			
		||||
    widget5: any = {};
 | 
			
		||||
    widget6: any = {};
 | 
			
		||||
    widget7: any = {};
 | 
			
		||||
 | 
			
		||||
    dateNow = Date.now();
 | 
			
		||||
 | 
			
		||||
    constructor(private projectsDashboardService: EcommerceDashboardService)
 | 
			
		||||
    {
 | 
			
		||||
        this.projects = this.projectsDashboardService.projects;
 | 
			
		||||
 | 
			
		||||
        this.selectedProject = this.projects[0];
 | 
			
		||||
 | 
			
		||||
        this.widgets = this.projectsDashboardService.widgets;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Widget 5
 | 
			
		||||
         */
 | 
			
		||||
        this.widget5 = {
 | 
			
		||||
            currentRange  : 'TW',
 | 
			
		||||
            xAxis         : true,
 | 
			
		||||
            yAxis         : true,
 | 
			
		||||
            gradient      : false,
 | 
			
		||||
            legend        : false,
 | 
			
		||||
            showXAxisLabel: false,
 | 
			
		||||
            xAxisLabel    : 'Days',
 | 
			
		||||
            showYAxisLabel: false,
 | 
			
		||||
            yAxisLabel    : 'Isues',
 | 
			
		||||
            scheme        : {
 | 
			
		||||
                domain: ['#42BFF7', '#C6ECFD', '#C7B42C', '#AAAAAA']
 | 
			
		||||
            },
 | 
			
		||||
            onSelect      : (ev) => {
 | 
			
		||||
                console.log(ev);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Widget 6
 | 
			
		||||
         */
 | 
			
		||||
        this.widget6 = {
 | 
			
		||||
            currentRange : 'TW',
 | 
			
		||||
            legend       : false,
 | 
			
		||||
            explodeSlices: false,
 | 
			
		||||
            labels       : true,
 | 
			
		||||
            doughnut     : true,
 | 
			
		||||
            gradient     : false,
 | 
			
		||||
            scheme       : {
 | 
			
		||||
                domain: ['#f44336', '#9c27b0', '#03a9f4', '#e91e63']
 | 
			
		||||
            },
 | 
			
		||||
            onSelect     : (ev) => {
 | 
			
		||||
                console.log(ev);
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Widget 7
 | 
			
		||||
         */
 | 
			
		||||
        this.widget7 = {
 | 
			
		||||
            currentRange: 'T'
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ngOnInit()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ngOnDestroy()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,62 @@
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
 | 
			
		||||
import { Observable } from 'rxjs/Observable';
 | 
			
		||||
import { HttpClient } from '@angular/common/http';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class EcommerceDashboardService implements Resolve<any>
 | 
			
		||||
{
 | 
			
		||||
    projects: any[];
 | 
			
		||||
    widgets: any[];
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private http: HttpClient
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Resolve
 | 
			
		||||
     * @param {ActivatedRouteSnapshot} route
 | 
			
		||||
     * @param {RouterStateSnapshot} state
 | 
			
		||||
     * @returns {Observable<any> | Promise<any> | any}
 | 
			
		||||
     */
 | 
			
		||||
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
            Promise.all([
 | 
			
		||||
                this.getProjects(),
 | 
			
		||||
                this.getWidgets()
 | 
			
		||||
            ]).then(
 | 
			
		||||
                () => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                },
 | 
			
		||||
                reject
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getProjects(): Promise<any>
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.get('api/projects-dashboard-projects')
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    this.projects = response;
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getWidgets(): Promise<any>
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.get('api/e-commerce-dashboard')
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    this.widgets = response;
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										91
									
								
								src/app/main/content/apps/e-commerce/e-commerce.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/app/main/content/apps/e-commerce/e-commerce.module.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,91 @@
 | 
			
		||||
import { NgModule } from '@angular/core';
 | 
			
		||||
import { RouterModule, Routes } from '@angular/router';
 | 
			
		||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
 | 
			
		||||
import { FuseEcommerceDashboardComponent } from './dashboard/dashboard.component';
 | 
			
		||||
import { EcommerceDashboardService } from './dashboard/dashboard.service';
 | 
			
		||||
import { SharedModule } from '../../../../core/modules/shared.module';
 | 
			
		||||
import { FuseWidgetModule } from '../../../../core/components/widget/widget.module';
 | 
			
		||||
import { FuseEcommerceProductsComponent } from './products/products.component';
 | 
			
		||||
import { EcommerceProductsService } from './products/products.service';
 | 
			
		||||
import { FuseEcommerceProductComponent } from './product/product.component';
 | 
			
		||||
import { EcommerceProductService } from './product/product.service';
 | 
			
		||||
import { FuseEcommerceOrdersComponent } from './orders/orders.component';
 | 
			
		||||
import { EcommerceOrdersService } from './orders/orders.service';
 | 
			
		||||
import { FuseEcommerceOrderComponent } from './order/order.component';
 | 
			
		||||
import { EcommerceOrderService } from './order/order.service';
 | 
			
		||||
import { AgmCoreModule } from '@agm/core';
 | 
			
		||||
 | 
			
		||||
const routes: Routes = [
 | 
			
		||||
    {
 | 
			
		||||
        path     : 'dashboard',
 | 
			
		||||
        component: FuseEcommerceDashboardComponent,
 | 
			
		||||
        resolve  : {
 | 
			
		||||
            data: EcommerceDashboardService
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path     : 'products',
 | 
			
		||||
        component: FuseEcommerceProductsComponent,
 | 
			
		||||
        resolve  : {
 | 
			
		||||
            data: EcommerceProductsService
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path     : 'products/:id',
 | 
			
		||||
        component: FuseEcommerceProductComponent,
 | 
			
		||||
        resolve  : {
 | 
			
		||||
            data: EcommerceProductService
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path     : 'products/:id/:handle',
 | 
			
		||||
        component: FuseEcommerceProductComponent,
 | 
			
		||||
        resolve  : {
 | 
			
		||||
            data: EcommerceProductService
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path     : 'orders',
 | 
			
		||||
        component: FuseEcommerceOrdersComponent,
 | 
			
		||||
        resolve  : {
 | 
			
		||||
            data: EcommerceOrdersService
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        path     : 'orders/:id',
 | 
			
		||||
        component: FuseEcommerceOrderComponent,
 | 
			
		||||
        resolve  : {
 | 
			
		||||
            data: EcommerceOrderService
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
@NgModule({
 | 
			
		||||
    imports     : [
 | 
			
		||||
        SharedModule,
 | 
			
		||||
        RouterModule.forChild(routes),
 | 
			
		||||
        FuseWidgetModule,
 | 
			
		||||
        NgxChartsModule,
 | 
			
		||||
        AgmCoreModule.forRoot({
 | 
			
		||||
            apiKey: 'AIzaSyD81ecsCj4yYpcXSLFcYU97PvRsE_X8Bx8'
 | 
			
		||||
        })
 | 
			
		||||
    ],
 | 
			
		||||
    declarations: [
 | 
			
		||||
        FuseEcommerceDashboardComponent,
 | 
			
		||||
        FuseEcommerceProductsComponent,
 | 
			
		||||
        FuseEcommerceProductComponent,
 | 
			
		||||
        FuseEcommerceOrdersComponent,
 | 
			
		||||
        FuseEcommerceOrderComponent
 | 
			
		||||
    ],
 | 
			
		||||
    providers   : [
 | 
			
		||||
        EcommerceDashboardService,
 | 
			
		||||
        EcommerceProductsService,
 | 
			
		||||
        EcommerceProductService,
 | 
			
		||||
        EcommerceOrdersService,
 | 
			
		||||
        EcommerceOrderService
 | 
			
		||||
    ]
 | 
			
		||||
})
 | 
			
		||||
export class FuseEcommerceModule
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								src/app/main/content/apps/e-commerce/order/order-statuses.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/app/main/content/apps/e-commerce/order/order-statuses.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,72 @@
 | 
			
		||||
export const orderStatuses = [
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 1,
 | 
			
		||||
        'name' : 'Awaiting check payment',
 | 
			
		||||
        'color': 'mat-blue-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 2,
 | 
			
		||||
        'name' : 'Payment accepted',
 | 
			
		||||
        'color': 'mat-green-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 3,
 | 
			
		||||
        'name' : 'Preparing the order',
 | 
			
		||||
        'color': 'mat-orange-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 4,
 | 
			
		||||
        'name' : 'Shipped',
 | 
			
		||||
        'color': 'mat-purple-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 5,
 | 
			
		||||
        'name' : 'Delivered',
 | 
			
		||||
        'color': 'mat-green-800-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 6,
 | 
			
		||||
        'name' : 'Canceled',
 | 
			
		||||
        'color': 'mat-pink-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 7,
 | 
			
		||||
        'name' : 'Refunded',
 | 
			
		||||
        'color': 'mat-red-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 8,
 | 
			
		||||
        'name' : 'Payment error',
 | 
			
		||||
        'color': 'mat-red-900-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 9,
 | 
			
		||||
        'name' : 'On pre-order (paid)',
 | 
			
		||||
        'color': 'mat-purple-300-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 10,
 | 
			
		||||
        'name' : 'Awaiting bank wire payment',
 | 
			
		||||
        'color': 'mat-blue-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 11,
 | 
			
		||||
        'name' : 'Awaiting PayPal payment',
 | 
			
		||||
        'color': 'mat-blue-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 12,
 | 
			
		||||
        'name' : 'Remote payment accepted',
 | 
			
		||||
        'color': 'mat-green-500-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 13,
 | 
			
		||||
        'name' : 'On pre-order (not paid)',
 | 
			
		||||
        'color': 'mat-purple-300-bg'
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        'id'   : 14,
 | 
			
		||||
        'name' : 'Awaiting Cash-on-delivery payment',
 | 
			
		||||
        'color': 'mat-blue-500-bg'
 | 
			
		||||
    }
 | 
			
		||||
];
 | 
			
		||||
							
								
								
									
										429
									
								
								src/app/main/content/apps/e-commerce/order/order.component.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										429
									
								
								src/app/main/content/apps/e-commerce/order/order.component.html
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,429 @@
 | 
			
		||||
<div id="order" class="page-layout carded fullwidth" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
    <!-- TOP BACKGROUND -->
 | 
			
		||||
    <div class="top-bg mat-accent-bg"></div>
 | 
			
		||||
    <!-- / TOP BACKGROUND -->
 | 
			
		||||
 | 
			
		||||
    <!-- CENTER -->
 | 
			
		||||
    <div class="center">
 | 
			
		||||
 | 
			
		||||
        <!-- HEADER -->
 | 
			
		||||
        <div class="header white-fg"
 | 
			
		||||
             fxLayout="row" fxLayoutAlign="space-between center">
 | 
			
		||||
 | 
			
		||||
            <!-- APP TITLE -->
 | 
			
		||||
            <div fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
 | 
			
		||||
                <button class="mr-16" mat-icon-button [routerLink]="'/apps/e-commerce/orders'">
 | 
			
		||||
                    <mat-icon>arrow_back</mat-icon>
 | 
			
		||||
                </button>
 | 
			
		||||
 | 
			
		||||
                <div fxLayout="column" fxLayoutAlign="start start"
 | 
			
		||||
                     *fuseIfOnDom [@animate]="{value:'*',params:{delay:'100ms',x:'-25px'}}">
 | 
			
		||||
                    <div class="h2">
 | 
			
		||||
                        Order {{order.reference}}
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="subtitle secondary-text">
 | 
			
		||||
                        <span>from</span>
 | 
			
		||||
                        <span>{{order.customer.firstName}} {{order.customer.lastName}}</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <!-- / APP TITLE -->
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / HEADER -->
 | 
			
		||||
 | 
			
		||||
        <!-- CONTENT CARD -->
 | 
			
		||||
        <div class="content-card mat-white-bg">
 | 
			
		||||
 | 
			
		||||
            <!-- CONTENT -->
 | 
			
		||||
            <div class="content">
 | 
			
		||||
 | 
			
		||||
                <mat-tab-group>
 | 
			
		||||
 | 
			
		||||
                    <mat-tab label="Order Details">
 | 
			
		||||
 | 
			
		||||
                        <div class="order-details tab-content p-24" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
                            <div class="section pb-48">
 | 
			
		||||
 | 
			
		||||
                                <div class="pb-16" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                                    <mat-icon class="m-0 mr-16">account_circle</mat-icon>
 | 
			
		||||
                                    <div class="h2 secondary-text">Customer</div>
 | 
			
		||||
                                </div>
 | 
			
		||||
 | 
			
		||||
                                <div class="customer">
 | 
			
		||||
                                    <table class="simple">
 | 
			
		||||
                                        <thead>
 | 
			
		||||
                                            <tr>
 | 
			
		||||
                                                <th>Name</th>
 | 
			
		||||
                                                <th>Email</th>
 | 
			
		||||
                                                <th>Phone</th>
 | 
			
		||||
                                                <th>Company</th>
 | 
			
		||||
                                            </tr>
 | 
			
		||||
                                        </thead>
 | 
			
		||||
                                        <tbody>
 | 
			
		||||
                                            <tr>
 | 
			
		||||
                                                <td>
 | 
			
		||||
                                                    <div fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                                                        <img class="avatar" [src]="order.customer.avatar">
 | 
			
		||||
                                                        <span class="name text-truncate">{{order.customer.firstName}} {{order.customer.lastName}}</span>
 | 
			
		||||
                                                    </div>
 | 
			
		||||
                                                </td>
 | 
			
		||||
                                                <td>
 | 
			
		||||
                                                    <span class="email text-truncate">{{order.customer.email}}</span>
 | 
			
		||||
                                                </td>
 | 
			
		||||
                                                <td>
 | 
			
		||||
                                                    <span class="phone text-truncate">{{order.customer.phone}}</span>
 | 
			
		||||
                                                </td>
 | 
			
		||||
                                                <td>
 | 
			
		||||
                                                    <span class="company text-truncate">{{order.customer.company}}</span>
 | 
			
		||||
                                                </td>
 | 
			
		||||
                                            </tr>
 | 
			
		||||
                                        </tbody>
 | 
			
		||||
                                    </table>
 | 
			
		||||
                                </div>
 | 
			
		||||
 | 
			
		||||
                                <mat-tab-group class="addresses">
 | 
			
		||||
 | 
			
		||||
                                    <mat-tab label="Shipping Address">
 | 
			
		||||
                                        <div fxFlex fxLayout="column" *fuseIfOnDom>
 | 
			
		||||
                                            <div class="address h4 py-24">{{order.customer.shippingAddress.address}}</div>
 | 
			
		||||
                                            <agm-map class="w-100-p h-400" [zoom]="15"
 | 
			
		||||
                                                     [latitude]="order.customer.shippingAddress.lat"
 | 
			
		||||
                                                     [longitude]="order.customer.shippingAddress.lng">
 | 
			
		||||
                                                <agm-marker [latitude]="order.customer.shippingAddress.lat"
 | 
			
		||||
                                                            [longitude]="order.customer.shippingAddress.lng">
 | 
			
		||||
                                                </agm-marker>
 | 
			
		||||
                                            </agm-map>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </mat-tab>
 | 
			
		||||
 | 
			
		||||
                                    <mat-tab label="Invoice Address" fxLayout="column">
 | 
			
		||||
                                        <div fxFlex fxLayout="column" *fuseIfOnDom>
 | 
			
		||||
                                            <div class="address h4 py-24">{{order.customer.invoiceAddress.address}}</div>
 | 
			
		||||
                                            <agm-map class="w-100-p h-400" [zoom]="15"
 | 
			
		||||
                                                     [latitude]="order.customer.invoiceAddress.lat"
 | 
			
		||||
                                                     [longitude]="order.customer.invoiceAddress.lng">
 | 
			
		||||
                                                <agm-marker [latitude]="order.customer.invoiceAddress.lat"
 | 
			
		||||
                                                            [longitude]="order.customer.invoiceAddress.lng">
 | 
			
		||||
                                                </agm-marker>
 | 
			
		||||
                                            </agm-map>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </mat-tab>
 | 
			
		||||
                                </mat-tab-group>
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
                            <div class="section pb-48">
 | 
			
		||||
 | 
			
		||||
                                <div class="pb-16" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                                    <mat-icon class="m-0 mr-16">access_time</mat-icon>
 | 
			
		||||
                                    <div class="h2 secondary-text">Order Status</div>
 | 
			
		||||
                                </div>
 | 
			
		||||
 | 
			
		||||
                                <table class="simple">
 | 
			
		||||
                                    <thead>
 | 
			
		||||
                                        <tr>
 | 
			
		||||
                                            <th>Status</th>
 | 
			
		||||
                                            <th>Updated On</th>
 | 
			
		||||
                                        </tr>
 | 
			
		||||
                                    </thead>
 | 
			
		||||
                                    <tbody>
 | 
			
		||||
 | 
			
		||||
                                        <tr *ngFor="let status of order.status">
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                <span class="status h6 p-4" [ngClass]="status.color">
 | 
			
		||||
                                                    {{status.name}}
 | 
			
		||||
                                                </span>
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                <span>
 | 
			
		||||
                                                    {{status.date | date}}
 | 
			
		||||
                                                </span>
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                        </tr>
 | 
			
		||||
                                    </tbody>
 | 
			
		||||
                                </table>
 | 
			
		||||
 | 
			
		||||
                                <form class="update-status p-24"
 | 
			
		||||
                                      (ngSubmit)="updateStatus()"
 | 
			
		||||
                                      [formGroup]="statusForm"
 | 
			
		||||
                                      fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
 | 
			
		||||
                                    <mat-form-field class="mr-16" fxFlex>
 | 
			
		||||
                                        <mat-select formControlName="newStatus"
 | 
			
		||||
                                                    placeholder="Select a status" required>
 | 
			
		||||
                                            <mat-option *ngFor="let status of orderStatuses"
 | 
			
		||||
                                                        [value]="status.id">
 | 
			
		||||
                                                {{status.name}}
 | 
			
		||||
                                            </mat-option>
 | 
			
		||||
                                        </mat-select>
 | 
			
		||||
                                    </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                    <button mat-raised-button class="mat-accent"
 | 
			
		||||
                                            [disabled]="statusForm.invalid">
 | 
			
		||||
                                        Update Status
 | 
			
		||||
                                    </button>
 | 
			
		||||
                                </form>
 | 
			
		||||
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
                            <div class="section pb-48">
 | 
			
		||||
 | 
			
		||||
                                <div class="pb-16" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                                    <mat-icon class="m-0 mr-16">attach_money</mat-icon>
 | 
			
		||||
                                    <div class="h2 secondary-text">Payment</div>
 | 
			
		||||
                                </div>
 | 
			
		||||
 | 
			
		||||
                                <table class="simple">
 | 
			
		||||
                                    <thead>
 | 
			
		||||
                                        <tr>
 | 
			
		||||
                                            <th>TransactionID</th>
 | 
			
		||||
                                            <th>Payment Method</th>
 | 
			
		||||
                                            <th>Amount</th>
 | 
			
		||||
                                            <th>Date</th>
 | 
			
		||||
                                        </tr>
 | 
			
		||||
                                    </thead>
 | 
			
		||||
                                    <tbody>
 | 
			
		||||
                                        <tr>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                <span class="text-truncate">
 | 
			
		||||
                                                    {{order.payment.transactionId}}
 | 
			
		||||
                                                </span>
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                <span class="text-truncate">
 | 
			
		||||
                                                    {{order.payment.method}}
 | 
			
		||||
                                                </span>
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                <span class="text-truncate">
 | 
			
		||||
                                                    {{order.payment.amount}}
 | 
			
		||||
                                                </span>
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                <span class="text-truncate">
 | 
			
		||||
                                                    {{order.payment.date | date}}
 | 
			
		||||
                                                </span>
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                        </tr>
 | 
			
		||||
                                    </tbody>
 | 
			
		||||
                                </table>
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                            <div class="section pb-48">
 | 
			
		||||
 | 
			
		||||
                                <div class="pb-16" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                                    <mat-icon class="m-0 mr-16">local_shipping</mat-icon>
 | 
			
		||||
                                    <div class="h2 secondary-text">Shipping</div>
 | 
			
		||||
                                </div>
 | 
			
		||||
 | 
			
		||||
                                <table class="simple">
 | 
			
		||||
                                    <thead>
 | 
			
		||||
                                        <tr>
 | 
			
		||||
                                            <th>Tracking Code</th>
 | 
			
		||||
                                            <th>Carrier</th>
 | 
			
		||||
                                            <th>Weight</th>
 | 
			
		||||
                                            <th>Fee</th>
 | 
			
		||||
                                            <th>Date</th>
 | 
			
		||||
                                        </tr>
 | 
			
		||||
                                    </thead>
 | 
			
		||||
                                    <tbody>
 | 
			
		||||
                                        <tr *ngFor="let shipping of order.shippingDetails">
 | 
			
		||||
                                            <td class="tracking-code">
 | 
			
		||||
                                                {{shipping.tracking}}
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                {{shipping.carrier}}
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                {{shipping.weight}}
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                {{shipping.fee}}
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                            <td>
 | 
			
		||||
                                                {{shipping.date}}
 | 
			
		||||
                                            </td>
 | 
			
		||||
                                        </tr>
 | 
			
		||||
                                    </tbody>
 | 
			
		||||
                                </table>
 | 
			
		||||
                            </div>
 | 
			
		||||
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </mat-tab>
 | 
			
		||||
 | 
			
		||||
                    <mat-tab label="Products">
 | 
			
		||||
                        <div class="products tab-content p-24" fusePerfectScrollbar>
 | 
			
		||||
                            <table class="simple">
 | 
			
		||||
                                <thead>
 | 
			
		||||
                                    <tr>
 | 
			
		||||
                                        <th>ID</th>
 | 
			
		||||
                                        <th>Image</th>
 | 
			
		||||
                                        <th>Name</th>
 | 
			
		||||
                                        <th>Price</th>
 | 
			
		||||
                                        <th>Quantity</th>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                </thead>
 | 
			
		||||
                                <tbody>
 | 
			
		||||
                                    <tr class="product-row"
 | 
			
		||||
                                        *ngFor="let product of order.products"
 | 
			
		||||
                                        [routerLink]="'/apps/e-commerce/products/'+product.id+'/'+product.handle">
 | 
			
		||||
                                        <td class="w-64">
 | 
			
		||||
                                            {{product.id}}
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                        <td class="w-80">
 | 
			
		||||
                                            <img class="product-image" [src]="product.image">
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                        <td>
 | 
			
		||||
                                            {{product.name}}
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                        <td>
 | 
			
		||||
                                            {{product.price}}
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                        <td>
 | 
			
		||||
                                            {{product.quantity}}
 | 
			
		||||
                                        </td>
 | 
			
		||||
                                    </tr>
 | 
			
		||||
                                </tbody>
 | 
			
		||||
                            </table>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </mat-tab>
 | 
			
		||||
 | 
			
		||||
                    <mat-tab label="Invoice">
 | 
			
		||||
 | 
			
		||||
                        <div class="invoice tab-content p-24" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
                            <div id="invoice" class="compact page-layout blank" fxLayout="row" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
                                <div class="invoice-container">
 | 
			
		||||
 | 
			
		||||
                                    <!-- INVOICE -->
 | 
			
		||||
                                    <div class="card">
 | 
			
		||||
 | 
			
		||||
                                        <div class="header">
 | 
			
		||||
                                            <div class="invoice-date">{{order.date}}</div>
 | 
			
		||||
 | 
			
		||||
                                            <div fxLayout="row" fxLayoutAlign="space-between stretch">
 | 
			
		||||
                                                <div class="client">
 | 
			
		||||
                                                    <div class="invoice-number" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                                                        <span class="title">INVOICE</span>
 | 
			
		||||
                                                        <span class="number">{{order.reference}}</span>
 | 
			
		||||
                                                    </div>
 | 
			
		||||
 | 
			
		||||
                                                    <div class="info">
 | 
			
		||||
                                                        <div class="title">
 | 
			
		||||
                                                            {{order.customer.firstName}}
 | 
			
		||||
                                                            {{order.customer.lastName}}
 | 
			
		||||
                                                        </div>
 | 
			
		||||
                                                        <div class="address">{{order.customer.invoiceAddress}}</div>
 | 
			
		||||
                                                        <div class="phone">{{order.customer.phone}}</div>
 | 
			
		||||
                                                        <div class="email">{{order.customer.email}}</div>
 | 
			
		||||
                                                    </div>
 | 
			
		||||
                                                </div>
 | 
			
		||||
 | 
			
		||||
                                                <div class="issuer mat-accent-bg" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                                                    <div class="logo">
 | 
			
		||||
                                                        <img src="assets/images/logos/fuse.svg">
 | 
			
		||||
                                                    </div>
 | 
			
		||||
 | 
			
		||||
                                                    <div class="info">
 | 
			
		||||
                                                        <div class="title">FUSE INC.</div>
 | 
			
		||||
                                                        <div class="address">2810 Country Club Road Cranford, NJ 07016</div>
 | 
			
		||||
                                                        <div class="phone">+66 123 455 87</div>
 | 
			
		||||
                                                        <div class="email">hello@fuseinc.com</div>
 | 
			
		||||
                                                        <div class="website">www.fuseinc.com</div>
 | 
			
		||||
                                                    </div>
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="content">
 | 
			
		||||
 | 
			
		||||
                                            <table class="simple invoice-table">
 | 
			
		||||
                                                <thead>
 | 
			
		||||
                                                    <tr>
 | 
			
		||||
                                                        <th>PRODUCT</th>
 | 
			
		||||
                                                        <th class="text-right">PRICE</th>
 | 
			
		||||
                                                        <th class="text-right">QUANTITY</th>
 | 
			
		||||
                                                        <th class="text-right">TOTAL</th>
 | 
			
		||||
                                                    </tr>
 | 
			
		||||
                                                </thead>
 | 
			
		||||
                                                <tbody>
 | 
			
		||||
                                                    <tr *ngFor="let product of order.products">
 | 
			
		||||
                                                        <td>
 | 
			
		||||
                                                            <div class="title">
 | 
			
		||||
                                                                {{product.name}}
 | 
			
		||||
                                                            </div>
 | 
			
		||||
                                                        </td>
 | 
			
		||||
                                                        <td class="text-right">
 | 
			
		||||
                                                            {{product.price | currency:'USD':true}}
 | 
			
		||||
                                                        </td>
 | 
			
		||||
                                                        <td class="text-right">
 | 
			
		||||
                                                            {{product.quantity}}
 | 
			
		||||
                                                        </td>
 | 
			
		||||
                                                        <td class="text-right">
 | 
			
		||||
                                                            {{product.total | currency:'USD':true}}
 | 
			
		||||
                                                        </td>
 | 
			
		||||
                                                    </tr>
 | 
			
		||||
                                                </tbody>
 | 
			
		||||
                                            </table>
 | 
			
		||||
 | 
			
		||||
                                            <table class="simple invoice-table-footer">
 | 
			
		||||
                                                <tbody>
 | 
			
		||||
                                                    <tr class="subtotal">
 | 
			
		||||
                                                        <td>SUBTOTAL</td>
 | 
			
		||||
                                                        <td>{{order.subtotal | currency:'USD':true}}</td>
 | 
			
		||||
                                                    </tr>
 | 
			
		||||
                                                    <tr class="tax">
 | 
			
		||||
                                                        <td>TAX</td>
 | 
			
		||||
                                                        <td>{{order.tax | currency:'USD':true}}</td>
 | 
			
		||||
                                                    </tr>
 | 
			
		||||
                                                    <tr class="discount">
 | 
			
		||||
                                                        <td>DISCOUNT</td>
 | 
			
		||||
                                                        <td>-{{order.discount | currency:'USD':true}}</td>
 | 
			
		||||
                                                    </tr>
 | 
			
		||||
                                                    <tr class="total">
 | 
			
		||||
                                                        <td>TOTAL</td>
 | 
			
		||||
                                                        <td>{{order.total | currency:'USD':true}}</td>
 | 
			
		||||
                                                    </tr>
 | 
			
		||||
                                                </tbody>
 | 
			
		||||
                                            </table>
 | 
			
		||||
                                        </div>
 | 
			
		||||
 | 
			
		||||
                                        <div class="footer">
 | 
			
		||||
                                            <div class="note">Please pay within 15 days. Thank you for your business.</div>
 | 
			
		||||
                                            <div fxLayout="row" fxLayoutAlign="start start">
 | 
			
		||||
                                                <div class="logo">
 | 
			
		||||
                                                    <img src="assets/images/logos/fuse.svg">
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                                <div class="small-note">
 | 
			
		||||
                                                    In condimentum malesuada efficitur. Mauris volutpat placerat auctor. Ut ac congue dolor. Quisque
 | 
			
		||||
                                                    scelerisque lacus sed feugiat fermentum. Cras aliquet facilisis pellentesque. Nunc hendrerit
 | 
			
		||||
                                                    quam at leo commodo, a suscipit tellus dapibus. Etiam at felis volutpat est mollis lacinia.
 | 
			
		||||
                                                    Mauris placerat sem sit amet velit mollis, in porttitor ex finibus. Proin eu nibh id libero
 | 
			
		||||
                                                    tincidunt lacinia et eget eros.
 | 
			
		||||
                                                </div>
 | 
			
		||||
                                            </div>
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                    <!-- / INVOICE -->
 | 
			
		||||
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </mat-tab>
 | 
			
		||||
 | 
			
		||||
                </mat-tab-group>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
            <!-- / CONTENT -->
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / CONTENT CARD -->
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- / CENTER -->
 | 
			
		||||
</div>
 | 
			
		||||
							
								
								
									
										395
									
								
								src/app/main/content/apps/e-commerce/order/order.component.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										395
									
								
								src/app/main/content/apps/e-commerce/order/order.component.scss
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,395 @@
 | 
			
		||||
@import "src/app/core/scss/fuse";
 | 
			
		||||
 | 
			
		||||
#order {
 | 
			
		||||
 | 
			
		||||
    .header {
 | 
			
		||||
 | 
			
		||||
        .subtitle {
 | 
			
		||||
            margin: 6px 0 0 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .content {
 | 
			
		||||
 | 
			
		||||
        .mat-tab-group,
 | 
			
		||||
        .mat-tab-body-wrapper,
 | 
			
		||||
        .tab-content {
 | 
			
		||||
            flex: 1 1 auto;
 | 
			
		||||
            max-width: 100%;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .tab-content {
 | 
			
		||||
            flex: 1 1 auto;
 | 
			
		||||
 | 
			
		||||
            &.products {
 | 
			
		||||
 | 
			
		||||
                .product-row {
 | 
			
		||||
                    cursor: pointer;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            &.invoice {
 | 
			
		||||
 | 
			
		||||
                #invoice {
 | 
			
		||||
 | 
			
		||||
                    &.compact {
 | 
			
		||||
                        padding: 0;
 | 
			
		||||
                        overflow: auto;
 | 
			
		||||
 | 
			
		||||
                        .invoice-container {
 | 
			
		||||
                            padding: 64px;
 | 
			
		||||
 | 
			
		||||
                            .card {
 | 
			
		||||
                                width: 1020px;
 | 
			
		||||
                                min-width: 1020px;
 | 
			
		||||
                                max-width: 1020px;
 | 
			
		||||
                                padding: 64px 88px;
 | 
			
		||||
                                overflow: hidden;
 | 
			
		||||
                                background: #FFFFFF;
 | 
			
		||||
                                @include mat-elevation(7);
 | 
			
		||||
 | 
			
		||||
                                .header {
 | 
			
		||||
 | 
			
		||||
                                    .invoice-date {
 | 
			
		||||
                                        font-size: 14px;
 | 
			
		||||
                                        color: rgba(0, 0, 0, 0.54);
 | 
			
		||||
                                        margin-bottom: 32px;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    .client {
 | 
			
		||||
 | 
			
		||||
                                        .invoice-number {
 | 
			
		||||
                                            font-size: 18px;
 | 
			
		||||
                                            padding-bottom: 2px;
 | 
			
		||||
 | 
			
		||||
                                            .title {
 | 
			
		||||
                                                color: rgba(0, 0, 0, 0.54);
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            .number {
 | 
			
		||||
                                                padding-left: 6px;
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .due-date {
 | 
			
		||||
                                            font-size: 18px;
 | 
			
		||||
                                            padding-bottom: 16px;
 | 
			
		||||
 | 
			
		||||
                                            .title {
 | 
			
		||||
                                                color: rgba(0, 0, 0, 0.54);
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            .date {
 | 
			
		||||
                                                padding-left: 6px;
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .info {
 | 
			
		||||
                                            color: rgba(0, 0, 0, 0.54);
 | 
			
		||||
                                            line-height: 22px;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    .issuer {
 | 
			
		||||
                                        margin-right: -88px;
 | 
			
		||||
                                        padding-right: 66px;
 | 
			
		||||
 | 
			
		||||
                                        .logo {
 | 
			
		||||
                                            width: 96px;
 | 
			
		||||
                                            padding: 0 8px;
 | 
			
		||||
                                            border-right: 1px solid rgba(255, 255, 255, 0.7);
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .info {
 | 
			
		||||
                                            padding: 16px;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                .content {
 | 
			
		||||
 | 
			
		||||
                                    .invoice-table {
 | 
			
		||||
                                        margin-top: 64px;
 | 
			
		||||
                                        font-size: 15px;
 | 
			
		||||
 | 
			
		||||
                                        thead {
 | 
			
		||||
 | 
			
		||||
                                            tr {
 | 
			
		||||
 | 
			
		||||
                                                th {
 | 
			
		||||
 | 
			
		||||
                                                    &:first-child {
 | 
			
		||||
                                                        padding-left: 8px;
 | 
			
		||||
                                                    }
 | 
			
		||||
 | 
			
		||||
                                                    &:last-child {
 | 
			
		||||
                                                        padding-right: 8px;
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        tbody {
 | 
			
		||||
 | 
			
		||||
                                            tr {
 | 
			
		||||
 | 
			
		||||
                                                td {
 | 
			
		||||
 | 
			
		||||
                                                    &:first-child {
 | 
			
		||||
                                                        padding-left: 8px;
 | 
			
		||||
                                                    }
 | 
			
		||||
 | 
			
		||||
                                                    &:last-child {
 | 
			
		||||
                                                        padding-right: 8px;
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .title {
 | 
			
		||||
                                            font-size: 16px;
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .detail {
 | 
			
		||||
                                            margin-top: 8px;
 | 
			
		||||
                                            font-size: 12px;
 | 
			
		||||
                                            color: rgba(0, 0, 0, 0.54);
 | 
			
		||||
                                            max-width: 360px;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    .invoice-table-footer {
 | 
			
		||||
                                        margin: 32px 0 72px 0;
 | 
			
		||||
 | 
			
		||||
                                        tr {
 | 
			
		||||
 | 
			
		||||
                                            td {
 | 
			
		||||
                                                text-align: right;
 | 
			
		||||
                                                font-size: 16px;
 | 
			
		||||
                                                font-weight: 500;
 | 
			
		||||
                                                color: rgba(0, 0, 0, 0.54);
 | 
			
		||||
                                                border-bottom: none;
 | 
			
		||||
                                                padding: 4px 8px;
 | 
			
		||||
 | 
			
		||||
                                                &:first-child {
 | 
			
		||||
                                                    text-align: left;
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            &.discount {
 | 
			
		||||
 | 
			
		||||
                                                td {
 | 
			
		||||
                                                    padding-bottom: 32px;
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            &.total {
 | 
			
		||||
 | 
			
		||||
                                                td {
 | 
			
		||||
                                                    padding: 24px 8px;
 | 
			
		||||
                                                    border-top: 1px solid rgba(0, 0, 0, 0.12);
 | 
			
		||||
                                                    font-size: 35px;
 | 
			
		||||
                                                    font-weight: 300;
 | 
			
		||||
                                                    color: rgba(0, 0, 0, 1);
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 | 
			
		||||
                                .footer {
 | 
			
		||||
 | 
			
		||||
                                    .note {
 | 
			
		||||
                                        font-size: 15px;
 | 
			
		||||
                                        font-weight: 500;
 | 
			
		||||
                                        margin-bottom: 24px;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    // IE10 fix
 | 
			
		||||
                                    .logo, .small-note {
 | 
			
		||||
                                        -ms-flex: 0 1 auto;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    .logo {
 | 
			
		||||
                                        width: 32px;
 | 
			
		||||
                                        min-width: 32px;
 | 
			
		||||
                                        margin-right: 24px;
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    .small-note {
 | 
			
		||||
                                        font-size: 12px;
 | 
			
		||||
                                        font-weight: 500;
 | 
			
		||||
                                        color: rgba(0, 0, 0, 0.54);
 | 
			
		||||
                                        line-height: 18px;
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                /* PRINT STYLES */
 | 
			
		||||
                @media print {
 | 
			
		||||
 | 
			
		||||
                    /* Invoice Specific Styles */
 | 
			
		||||
                    #invoice {
 | 
			
		||||
 | 
			
		||||
                        &.compact {
 | 
			
		||||
 | 
			
		||||
                            .invoice-container {
 | 
			
		||||
                                padding: 0;
 | 
			
		||||
 | 
			
		||||
                                .card {
 | 
			
		||||
                                    width: 100%;
 | 
			
		||||
                                    min-width: 0;
 | 
			
		||||
                                    background: none;
 | 
			
		||||
                                    padding: 0;
 | 
			
		||||
                                    box-shadow: none;
 | 
			
		||||
 | 
			
		||||
                                    .header {
 | 
			
		||||
 | 
			
		||||
                                        .invoice-date {
 | 
			
		||||
                                            margin-bottom: 16pt;
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .issuer {
 | 
			
		||||
                                            padding-right: 0;
 | 
			
		||||
                                            margin-right: 0;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    .content {
 | 
			
		||||
 | 
			
		||||
                                        .invoice-table {
 | 
			
		||||
                                            margin-top: 16pt;
 | 
			
		||||
 | 
			
		||||
                                            thead {
 | 
			
		||||
 | 
			
		||||
                                                tr {
 | 
			
		||||
 | 
			
		||||
                                                    th {
 | 
			
		||||
                                                        font-size: 10pt;
 | 
			
		||||
                                                        max-width: 60pt;
 | 
			
		||||
 | 
			
		||||
                                                        &:first-child {
 | 
			
		||||
                                                            padding-left: 0;
 | 
			
		||||
                                                        }
 | 
			
		||||
 | 
			
		||||
                                                        &:last-child {
 | 
			
		||||
                                                            padding-right: 0;
 | 
			
		||||
                                                        }
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            tbody {
 | 
			
		||||
 | 
			
		||||
                                                tr {
 | 
			
		||||
 | 
			
		||||
                                                    td {
 | 
			
		||||
 | 
			
		||||
                                                        &:first-child {
 | 
			
		||||
                                                            padding-left: 0;
 | 
			
		||||
                                                        }
 | 
			
		||||
 | 
			
		||||
                                                        &:last-child {
 | 
			
		||||
                                                            padding-right: 0;
 | 
			
		||||
                                                        }
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            .title {
 | 
			
		||||
                                                font-size: 10pt;
 | 
			
		||||
                                            }
 | 
			
		||||
 | 
			
		||||
                                            .detail {
 | 
			
		||||
                                                margin-top: 4pt;
 | 
			
		||||
                                                font-size: 9pt;
 | 
			
		||||
                                                max-width: none;
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .invoice-table-footer {
 | 
			
		||||
                                            margin: 16pt 0;
 | 
			
		||||
 | 
			
		||||
                                            tr {
 | 
			
		||||
 | 
			
		||||
                                                td {
 | 
			
		||||
                                                    font-size: 13pt;
 | 
			
		||||
                                                    padding: 4pt 4pt;
 | 
			
		||||
 | 
			
		||||
                                                    &:first-child {
 | 
			
		||||
                                                        text-align: left;
 | 
			
		||||
                                                        padding-left: 0;
 | 
			
		||||
                                                    }
 | 
			
		||||
 | 
			
		||||
                                                    &:last-child {
 | 
			
		||||
                                                        padding-right: 0;
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
 | 
			
		||||
                                                &.discount {
 | 
			
		||||
 | 
			
		||||
                                                    td {
 | 
			
		||||
                                                        padding-bottom: 16pt;
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
 | 
			
		||||
                                                &.total {
 | 
			
		||||
 | 
			
		||||
                                                    td {
 | 
			
		||||
                                                        padding: 16pt 4pt 0 4pt;
 | 
			
		||||
                                                        font-size: 16pt;
 | 
			
		||||
 | 
			
		||||
                                                        &:first-child {
 | 
			
		||||
                                                            padding-left: 0;
 | 
			
		||||
                                                        }
 | 
			
		||||
 | 
			
		||||
                                                        &:last-child {
 | 
			
		||||
                                                            padding-right: 0;
 | 
			
		||||
                                                        }
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
 | 
			
		||||
                                    .footer {
 | 
			
		||||
 | 
			
		||||
                                        .note {
 | 
			
		||||
                                            font-size: 10pt;
 | 
			
		||||
                                            margin-bottom: 8pt;
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .logo {
 | 
			
		||||
                                            margin-right: 8pt;
 | 
			
		||||
                                        }
 | 
			
		||||
 | 
			
		||||
                                        .small-note {
 | 
			
		||||
                                            font-size: 8pt;
 | 
			
		||||
                                            line-height: normal;
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-tab-body-content {
 | 
			
		||||
            display: flex;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-tab-label {
 | 
			
		||||
            height: 64px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        table {
 | 
			
		||||
            table-layout: fixed;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,78 @@
 | 
			
		||||
import { Component, ElementRef, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
 | 
			
		||||
import { EcommerceOrderService } from './order.service';
 | 
			
		||||
import { fuseAnimations } from '../../../../../core/animations';
 | 
			
		||||
import 'rxjs/add/operator/startWith';
 | 
			
		||||
import 'rxjs/add/observable/merge';
 | 
			
		||||
import 'rxjs/add/operator/map';
 | 
			
		||||
import 'rxjs/add/operator/debounceTime';
 | 
			
		||||
import 'rxjs/add/operator/distinctUntilChanged';
 | 
			
		||||
import 'rxjs/add/observable/fromEvent';
 | 
			
		||||
import { Subscription } from 'rxjs/Subscription';
 | 
			
		||||
import { Order } from './order.model';
 | 
			
		||||
import { FormBuilder, FormGroup } from '@angular/forms';
 | 
			
		||||
import { FuseUtils } from '../../../../../core/fuseUtils';
 | 
			
		||||
import { MatSnackBar } from '@angular/material';
 | 
			
		||||
import { Location } from '@angular/common';
 | 
			
		||||
import { orderStatuses } from './order-statuses';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector     : 'fuse-e-commerce-order',
 | 
			
		||||
    templateUrl  : './order.component.html',
 | 
			
		||||
    styleUrls    : ['./order.component.scss'],
 | 
			
		||||
    encapsulation: ViewEncapsulation.None,
 | 
			
		||||
    animations   : fuseAnimations
 | 
			
		||||
})
 | 
			
		||||
export class FuseEcommerceOrderComponent implements OnInit, OnDestroy
 | 
			
		||||
{
 | 
			
		||||
    order = new Order();
 | 
			
		||||
    onOrderChanged: Subscription;
 | 
			
		||||
    statusForm: FormGroup;
 | 
			
		||||
    orderStatuses = orderStatuses;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private orderService: EcommerceOrderService,
 | 
			
		||||
        private formBuilder: FormBuilder,
 | 
			
		||||
        public snackBar: MatSnackBar,
 | 
			
		||||
        private location: Location
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ngOnInit()
 | 
			
		||||
    {
 | 
			
		||||
        // Subscribe to update order on changes
 | 
			
		||||
        this.onOrderChanged =
 | 
			
		||||
            this.orderService.onOrderChanged
 | 
			
		||||
                .subscribe(order => {
 | 
			
		||||
                    this.order = new Order(order);
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
        this.statusForm = this.formBuilder.group({
 | 
			
		||||
            newStatus: ['']
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    updateStatus()
 | 
			
		||||
    {
 | 
			
		||||
        const newStatusId = Number.parseInt(this.statusForm.get('newStatus').value);
 | 
			
		||||
 | 
			
		||||
        if ( !newStatusId )
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        const newStatus = this.orderStatuses.find((status) => {
 | 
			
		||||
            return status.id === newStatusId;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        newStatus['date'] = new Date().toString();
 | 
			
		||||
 | 
			
		||||
        this.order.status.unshift(newStatus);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ngOnDestroy()
 | 
			
		||||
    {
 | 
			
		||||
        this.onOrderChanged.unsubscribe();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										34
									
								
								src/app/main/content/apps/e-commerce/order/order.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/app/main/content/apps/e-commerce/order/order.model.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,34 @@
 | 
			
		||||
import { FuseUtils } from '../../../../../core/fuseUtils';
 | 
			
		||||
 | 
			
		||||
export class Order
 | 
			
		||||
{
 | 
			
		||||
    id: string;
 | 
			
		||||
    reference: string;
 | 
			
		||||
    subtotal: string;
 | 
			
		||||
    tax: string;
 | 
			
		||||
    discount: string;
 | 
			
		||||
    total: string;
 | 
			
		||||
    date: string;
 | 
			
		||||
    customer: any;
 | 
			
		||||
    products: any[];
 | 
			
		||||
    status: any[];
 | 
			
		||||
    payment: any;
 | 
			
		||||
    shippingDetails: any[];
 | 
			
		||||
 | 
			
		||||
    constructor(order?)
 | 
			
		||||
    {
 | 
			
		||||
        order = order || {};
 | 
			
		||||
        this.id = order.id || FuseUtils.generateGUID();
 | 
			
		||||
        this.reference = order.reference || FuseUtils.generateGUID();
 | 
			
		||||
        this.subtotal = order.subtotal || 0;
 | 
			
		||||
        this.tax = order.tax || 0;
 | 
			
		||||
        this.discount = order.discount || 0;
 | 
			
		||||
        this.total = order.total || 0;
 | 
			
		||||
        this.date = order.date || '';
 | 
			
		||||
        this.customer = order.customer || {};
 | 
			
		||||
        this.products = order.products || [];
 | 
			
		||||
        this.status = order.status || [];
 | 
			
		||||
        this.payment = order.payment || {};
 | 
			
		||||
        this.shippingDetails = order.shippingDetails || [];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										75
									
								
								src/app/main/content/apps/e-commerce/order/order.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								src/app/main/content/apps/e-commerce/order/order.service.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,75 @@
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
 | 
			
		||||
import { Observable } from 'rxjs/Observable';
 | 
			
		||||
import { HttpClient } from '@angular/common/http';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class EcommerceOrderService implements Resolve<any>
 | 
			
		||||
{
 | 
			
		||||
    routeParams: any;
 | 
			
		||||
    order: any;
 | 
			
		||||
    onOrderChanged: BehaviorSubject<any> = new BehaviorSubject({});
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private http: HttpClient
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Resolve
 | 
			
		||||
     * @param {ActivatedRouteSnapshot} route
 | 
			
		||||
     * @param {RouterStateSnapshot} state
 | 
			
		||||
     * @returns {Observable<any> | Promise<any> | any}
 | 
			
		||||
     */
 | 
			
		||||
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        this.routeParams = route.params;
 | 
			
		||||
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
            Promise.all([
 | 
			
		||||
                this.getOrder()
 | 
			
		||||
            ]).then(
 | 
			
		||||
                () => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                },
 | 
			
		||||
                reject
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getOrder(): Promise<any>
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.get('api/e-commerce-orders/' + this.routeParams.id)
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    this.order = response;
 | 
			
		||||
                    this.onOrderChanged.next(this.order);
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    saveOrder(order)
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.post('api/e-commerce-orders/' + order.id, order)
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addOrder(order)
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.post('api/e-commerce-orders/', order)
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,133 @@
 | 
			
		||||
<div id="orders" class="page-layout carded fullwidth" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
    <!-- TOP BACKGROUND -->
 | 
			
		||||
    <div class="top-bg mat-accent-bg"></div>
 | 
			
		||||
    <!-- / TOP BACKGROUND -->
 | 
			
		||||
 | 
			
		||||
    <!-- CENTER -->
 | 
			
		||||
    <div class="center">
 | 
			
		||||
 | 
			
		||||
        <!-- HEADER -->
 | 
			
		||||
        <div class="header white-fg"
 | 
			
		||||
             fxLayout="column" fxLayoutAlign="center center"
 | 
			
		||||
             fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="space-between center">
 | 
			
		||||
 | 
			
		||||
            <!-- APP TITLE -->
 | 
			
		||||
            <div class="logo"
 | 
			
		||||
                 fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                <mat-icon class="logo-icon mr-16" *fuseIfOnDom [@animate]="{value:'*',params:{delay:'50ms',scale:'0.2'}}">shopping_basket</mat-icon>
 | 
			
		||||
                <span class="logo-text h1" *fuseIfOnDom [@animate]="{value:'*',params:{delay:'100ms',x:'-25px'}}">Orders</span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <!-- / APP TITLE -->
 | 
			
		||||
 | 
			
		||||
            <!-- SEARCH -->
 | 
			
		||||
            <div class="search-input-wrapper ml-8 m-sm-0"
 | 
			
		||||
                 fxFlex="1 0 auto" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                <label for="search" class="mr-8">
 | 
			
		||||
                    <mat-icon class="secondary-text">search</mat-icon>
 | 
			
		||||
                </label>
 | 
			
		||||
                <mat-form-field floatPlaceholder="never" fxFlex="1 0 auto">
 | 
			
		||||
                    <input id="search" matInput #filter placeholder="Search">
 | 
			
		||||
                </mat-form-field>
 | 
			
		||||
            </div>
 | 
			
		||||
            <!-- / SEARCH -->
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / HEADER -->
 | 
			
		||||
 | 
			
		||||
        <!-- CONTENT CARD -->
 | 
			
		||||
        <div class="content-card mat-white-bg">
 | 
			
		||||
 | 
			
		||||
            <mat-table class="orders-table"
 | 
			
		||||
                       #table [dataSource]="dataSource"
 | 
			
		||||
                       matSort
 | 
			
		||||
                       [@animateStagger]="{value:'50'}"
 | 
			
		||||
                       fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
                <!-- ID Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="id">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header>ID</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let order">
 | 
			
		||||
                        <p class="text-truncate">{{order.id}}</p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Reference Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="reference">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>Reference</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let order" fxHide fxShow.gt-sm>
 | 
			
		||||
                        <p class="text-truncate">{{order.reference}}</p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Name Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="customer">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header>Customer</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let order">
 | 
			
		||||
                        <p class="text-truncate">
 | 
			
		||||
                            {{order.customer.firstName}}
 | 
			
		||||
                            {{order.customer.lastName}}
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Total Price Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="total">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header fxHide fxShow.gt-md>Total</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let order" fxHide fxShow.gt-md>
 | 
			
		||||
                        <p class="total-price text-truncate">
 | 
			
		||||
                            {{order.total | currency:'USD':true}}
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Payment Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="payment">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>Payment</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let order" fxHide fxShow.gt-sm>
 | 
			
		||||
                        <p class="text-truncate">
 | 
			
		||||
                            {{order.payment.method}}
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Status Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="status">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header >Status</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let order">
 | 
			
		||||
                        <p class="status text-truncate h6 p-4" [ngClass]="order.status[0].color">
 | 
			
		||||
                            {{order.status[0].name}}
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Date Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="date">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>Date</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let order" fxHide fxShow.gt-sm>
 | 
			
		||||
                        <p class="text-truncate">
 | 
			
		||||
                            {{order.date}}
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <mat-header-row *cdkHeaderRowDef="displayedColumns"></mat-header-row>
 | 
			
		||||
 | 
			
		||||
                <mat-row *cdkRowDef="let order; columns: displayedColumns;"
 | 
			
		||||
                         class="order"
 | 
			
		||||
                         matRipple
 | 
			
		||||
                         [routerLink]="'/apps/e-commerce/orders/'+order.id">
 | 
			
		||||
                </mat-row>
 | 
			
		||||
            </mat-table>
 | 
			
		||||
 | 
			
		||||
            <mat-paginator #paginator
 | 
			
		||||
                           [length]="dataSource.filteredData.length"
 | 
			
		||||
                           [pageIndex]="0"
 | 
			
		||||
                           [pageSize]="10"
 | 
			
		||||
                           [pageSizeOptions]="[5, 10, 25, 100]">
 | 
			
		||||
            </mat-paginator>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / CONTENT CARD -->
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- / CENTER -->
 | 
			
		||||
</div>
 | 
			
		||||
@ -0,0 +1,73 @@
 | 
			
		||||
:host {
 | 
			
		||||
 | 
			
		||||
    .header {
 | 
			
		||||
 | 
			
		||||
        .search-input-wrapper {
 | 
			
		||||
            max-width: 480px;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .mat-tab-group,
 | 
			
		||||
    .mat-tab-body-wrapper,
 | 
			
		||||
    .tab-content{
 | 
			
		||||
        flex: 1 1 auto;
 | 
			
		||||
        max-width: 100%;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .orders-table {
 | 
			
		||||
        flex: 1 1 auto;
 | 
			
		||||
        border-bottom: 1px solid rgba(0, 0, 0, .12);
 | 
			
		||||
 | 
			
		||||
        .mat-header-row {
 | 
			
		||||
            min-height: 64px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .order {
 | 
			
		||||
            position: relative;
 | 
			
		||||
            cursor: pointer;
 | 
			
		||||
            height: 84px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-cell {
 | 
			
		||||
            min-width: 0;
 | 
			
		||||
            display: flex;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-column-id {
 | 
			
		||||
            flex: 0 1 84px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-column-image {
 | 
			
		||||
            flex: 0 1 84px;
 | 
			
		||||
 | 
			
		||||
            .product-image {
 | 
			
		||||
                width: 52px;
 | 
			
		||||
                height: 52px;
 | 
			
		||||
                border: 1px solid rgba(0, 0, 0, .12);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-column-buttons {
 | 
			
		||||
            flex: 0 1 80px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .quantity-indicator {
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            vertical-align: middle;
 | 
			
		||||
            width: 8px;
 | 
			
		||||
            height: 8px;
 | 
			
		||||
            border-radius: 4px;
 | 
			
		||||
            margin-right: 8px;
 | 
			
		||||
 | 
			
		||||
            & + span {
 | 
			
		||||
                display: inline-block;
 | 
			
		||||
                vertical-align: middle;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .active-icon {
 | 
			
		||||
            border-radius: 50%;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										169
									
								
								src/app/main/content/apps/e-commerce/orders/orders.component.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/app/main/content/apps/e-commerce/orders/orders.component.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,169 @@
 | 
			
		||||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
 | 
			
		||||
import { EcommerceOrdersService } from './orders.service';
 | 
			
		||||
import { DataSource } from '@angular/cdk/collections';
 | 
			
		||||
import { Observable } from 'rxjs/Observable';
 | 
			
		||||
import { fuseAnimations } from '../../../../../core/animations';
 | 
			
		||||
import { MatPaginator, MatSort } from '@angular/material';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 | 
			
		||||
import 'rxjs/add/operator/startWith';
 | 
			
		||||
import 'rxjs/add/observable/merge';
 | 
			
		||||
import 'rxjs/add/operator/map';
 | 
			
		||||
import 'rxjs/add/operator/debounceTime';
 | 
			
		||||
import 'rxjs/add/operator/distinctUntilChanged';
 | 
			
		||||
import 'rxjs/add/observable/fromEvent';
 | 
			
		||||
import { FuseUtils } from '../../../../../core/fuseUtils';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector   : 'fuse-e-commerce-orders',
 | 
			
		||||
    templateUrl: './orders.component.html',
 | 
			
		||||
    styleUrls  : ['./orders.component.scss'],
 | 
			
		||||
    animations : fuseAnimations
 | 
			
		||||
})
 | 
			
		||||
export class FuseEcommerceOrdersComponent implements OnInit
 | 
			
		||||
{
 | 
			
		||||
    dataSource: FilesDataSource | null;
 | 
			
		||||
    displayedColumns = ['id', 'reference', 'customer', 'total', 'payment', 'status', 'date'];
 | 
			
		||||
 | 
			
		||||
    @ViewChild(MatPaginator) paginator: MatPaginator;
 | 
			
		||||
    @ViewChild('filter') filter: ElementRef;
 | 
			
		||||
    @ViewChild(MatSort) sort: MatSort;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private ordersService: EcommerceOrdersService
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ngOnInit()
 | 
			
		||||
    {
 | 
			
		||||
        this.dataSource = new FilesDataSource(this.ordersService, this.paginator, this.sort);
 | 
			
		||||
 | 
			
		||||
        Observable.fromEvent(this.filter.nativeElement, 'keyup')
 | 
			
		||||
                  .debounceTime(150)
 | 
			
		||||
                  .distinctUntilChanged()
 | 
			
		||||
                  .subscribe(() => {
 | 
			
		||||
                      if ( !this.dataSource )
 | 
			
		||||
                      {
 | 
			
		||||
                          return;
 | 
			
		||||
                      }
 | 
			
		||||
                      this.dataSource.filter = this.filter.nativeElement.value;
 | 
			
		||||
                  });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class FilesDataSource extends DataSource<any>
 | 
			
		||||
{
 | 
			
		||||
    _filterChange = new BehaviorSubject('');
 | 
			
		||||
    _filteredDataChange = new BehaviorSubject('');
 | 
			
		||||
 | 
			
		||||
    get filteredData(): any
 | 
			
		||||
    {
 | 
			
		||||
        return this._filteredDataChange.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set filteredData(value: any)
 | 
			
		||||
    {
 | 
			
		||||
        this._filteredDataChange.next(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get filter(): string
 | 
			
		||||
    {
 | 
			
		||||
        return this._filterChange.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set filter(filter: string)
 | 
			
		||||
    {
 | 
			
		||||
        this._filterChange.next(filter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private ordersService: EcommerceOrdersService,
 | 
			
		||||
        private _paginator: MatPaginator,
 | 
			
		||||
        private _sort: MatSort
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
        super();
 | 
			
		||||
        this.filteredData = this.ordersService.orders;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Connect function called by the table to retrieve one stream containing the data to render. */
 | 
			
		||||
    connect(): Observable<any[]>
 | 
			
		||||
    {
 | 
			
		||||
        const displayDataChanges = [
 | 
			
		||||
            this.ordersService.onOrdersChanged,
 | 
			
		||||
            this._paginator.page,
 | 
			
		||||
            this._filterChange,
 | 
			
		||||
            this._sort.sortChange
 | 
			
		||||
        ];
 | 
			
		||||
        return Observable.merge(...displayDataChanges).map(() => {
 | 
			
		||||
            let data = this.ordersService.orders.slice();
 | 
			
		||||
 | 
			
		||||
            data = this.filterData(data);
 | 
			
		||||
 | 
			
		||||
            this.filteredData = [...data];
 | 
			
		||||
 | 
			
		||||
            data = this.sortData(data);
 | 
			
		||||
 | 
			
		||||
            // Grab the page's slice of data.
 | 
			
		||||
            const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
 | 
			
		||||
            return data.splice(startIndex, this._paginator.pageSize);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    filterData(data)
 | 
			
		||||
    {
 | 
			
		||||
        if ( !this.filter )
 | 
			
		||||
        {
 | 
			
		||||
            return data;
 | 
			
		||||
        }
 | 
			
		||||
        return FuseUtils.filterArrayByString(data, this.filter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sortData(data): any[]
 | 
			
		||||
    {
 | 
			
		||||
        if ( !this._sort.active || this._sort.direction === '' )
 | 
			
		||||
        {
 | 
			
		||||
            return data;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return data.sort((a, b) => {
 | 
			
		||||
            let propertyA: number | string = '';
 | 
			
		||||
            let propertyB: number | string = '';
 | 
			
		||||
 | 
			
		||||
            switch ( this._sort.active )
 | 
			
		||||
            {
 | 
			
		||||
                case 'id':
 | 
			
		||||
                    [propertyA, propertyB] = [a.id, b.id];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'reference':
 | 
			
		||||
                    [propertyA, propertyB] = [a.reference, b.reference];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'customer':
 | 
			
		||||
                    [propertyA, propertyB] = [a.customer.firstName, b.customer.firstName];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'total':
 | 
			
		||||
                    [propertyA, propertyB] = [a.total, b.total];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'payment':
 | 
			
		||||
                    [propertyA, propertyB] = [a.payment.method, b.payment.method];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'status':
 | 
			
		||||
                    [propertyA, propertyB] = [a.status[0].name, b.status[0].name];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'date':
 | 
			
		||||
                    [propertyA, propertyB] = [a.date, b.date];
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
 | 
			
		||||
            const valueB = isNaN(+propertyB) ? propertyB : +propertyB;
 | 
			
		||||
 | 
			
		||||
            return (valueA < valueB ? -1 : 1) * (this._sort.direction === 'asc' ? 1 : -1);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disconnect()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,52 @@
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
 | 
			
		||||
import { Observable } from 'rxjs/Observable';
 | 
			
		||||
import { HttpClient } from '@angular/common/http';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class EcommerceOrdersService implements Resolve<any>
 | 
			
		||||
{
 | 
			
		||||
    orders: any[];
 | 
			
		||||
    onOrdersChanged: BehaviorSubject<any> = new BehaviorSubject({});
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private http: HttpClient
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Resolve
 | 
			
		||||
     * @param {ActivatedRouteSnapshot} route
 | 
			
		||||
     * @param {RouterStateSnapshot} state
 | 
			
		||||
     * @returns {Observable<any> | Promise<any> | any}
 | 
			
		||||
     */
 | 
			
		||||
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
            Promise.all([
 | 
			
		||||
                this.getOrders()
 | 
			
		||||
            ]).then(
 | 
			
		||||
                () => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                },
 | 
			
		||||
                reject
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getOrders(): Promise<any>
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.get('api/e-commerce-orders')
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    this.orders = response;
 | 
			
		||||
                    this.onOrdersChanged.next(this.orders);
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,255 @@
 | 
			
		||||
<div id="product" class="page-layout carded fullwidth" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
    <!-- TOP BACKGROUND -->
 | 
			
		||||
    <div class="top-bg mat-accent-bg"></div>
 | 
			
		||||
    <!-- / TOP BACKGROUND -->
 | 
			
		||||
 | 
			
		||||
    <!-- CENTER -->
 | 
			
		||||
    <div class="center">
 | 
			
		||||
 | 
			
		||||
        <!-- HEADER -->
 | 
			
		||||
        <div class="header white-fg" fxLayout="row" fxLayoutAlign="space-between center">
 | 
			
		||||
 | 
			
		||||
            <!-- APP TITLE -->
 | 
			
		||||
            <div fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
 | 
			
		||||
                <button class="mr-0 mr-sm-16" mat-icon-button [routerLink]="'/apps/e-commerce/products'">
 | 
			
		||||
                    <mat-icon>arrow_back</mat-icon>
 | 
			
		||||
                </button>
 | 
			
		||||
 | 
			
		||||
                <div class="product-image mr-8 mr-sm-16" *fuseIfOnDom [@animate]="{value:'*',params:{delay:'50ms',scale:'0.2'}}">
 | 
			
		||||
                    <img *ngIf="product.images[0]" [src]="product.images[0].url">
 | 
			
		||||
                    <img *ngIf="!product.images[0]" [src]="'assets/images/ecommerce/product-image-placeholder.png'">
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div fxLayout="column" fxLayoutAlign="start start"
 | 
			
		||||
                     *fuseIfOnDom [@animate]="{value:'*',params:{delay:'100ms',x:'-25px'}}">
 | 
			
		||||
                    <div class="h2" *ngIf="pageType ==='edit'">
 | 
			
		||||
                        {{product.name}}
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="h2" *ngIf="pageType ==='new'">
 | 
			
		||||
                        New Product
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="subtitle secondary-text">
 | 
			
		||||
                        <span>Product Detail</span>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <!-- / APP TITLE -->
 | 
			
		||||
 | 
			
		||||
            <button mat-raised-button
 | 
			
		||||
                    class="save-product-button mat-white-bg mt-16 mt-sm-0"
 | 
			
		||||
                    [disabled]="productForm.invalid"
 | 
			
		||||
                    *ngIf="pageType ==='new'" (click)="addProduct()">
 | 
			
		||||
                <span>ADD</span>
 | 
			
		||||
            </button>
 | 
			
		||||
 | 
			
		||||
            <button mat-raised-button
 | 
			
		||||
                    class="save-product-button mat-white-bg mt-16 mt-sm-0"
 | 
			
		||||
                    [disabled]="productForm.invalid || productForm.pristine"
 | 
			
		||||
                    *ngIf="pageType ==='edit'" (click)="saveProduct()">
 | 
			
		||||
                <span>SAVE</span>
 | 
			
		||||
            </button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / HEADER -->
 | 
			
		||||
 | 
			
		||||
        <!-- CONTENT CARD -->
 | 
			
		||||
        <div class="content-card mat-white-bg">
 | 
			
		||||
 | 
			
		||||
            <!-- CONTENT -->
 | 
			
		||||
            <div class="content">
 | 
			
		||||
 | 
			
		||||
                <form name="productForm" [formGroup]="productForm" class="product w-100-p" fxLayout="column" fxFlex>
 | 
			
		||||
 | 
			
		||||
                    <mat-tab-group>
 | 
			
		||||
 | 
			
		||||
                        <mat-tab label="Basic Info">
 | 
			
		||||
                            <div class="tab-content p-24" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="name"
 | 
			
		||||
                                           formControlName="name"
 | 
			
		||||
                                           placeholder="Product Name"
 | 
			
		||||
                                           required>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <textarea matInput
 | 
			
		||||
                                              name="description"
 | 
			
		||||
                                              formControlName="description"
 | 
			
		||||
                                              placeholder="Product Description"
 | 
			
		||||
                                              rows="10">
 | 
			
		||||
                                    </textarea>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                <h3 class="mb-0">Categories</h3>
 | 
			
		||||
                                <mat-form-field class="w-100-p" floatPlaceholder="never">
 | 
			
		||||
                                    <mat-chip-list matPrefix #categoryList
 | 
			
		||||
                                                   name="categories"
 | 
			
		||||
                                                   formControlName="categories">
 | 
			
		||||
 | 
			
		||||
                                        <mat-chip *ngFor="let category of product.categories"
 | 
			
		||||
                                                  removable="true" (remove)="product.removeCategory(category)">
 | 
			
		||||
                                            {{category}}
 | 
			
		||||
                                            <mat-icon matChipRemove>cancel</mat-icon>
 | 
			
		||||
                                        </mat-chip>
 | 
			
		||||
                                    </mat-chip-list>
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           matChipInputAddOnBlur="true"
 | 
			
		||||
                                           (matChipInputTokenEnd)="product.addCategory($event)"
 | 
			
		||||
                                           placeholder="Add category..."
 | 
			
		||||
                                           [matChipInputFor]="categoryList"/>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                <h3 class="mb-0">Tags</h3>
 | 
			
		||||
                                <mat-form-field class="w-100-p" floatPlaceholder="never">
 | 
			
		||||
                                    <mat-chip-list matPrefix #tagList
 | 
			
		||||
                                                   name="tags"
 | 
			
		||||
                                                   formControlName="tags">
 | 
			
		||||
 | 
			
		||||
                                        <mat-chip *ngFor="let tag of product.tags"
 | 
			
		||||
                                                  removable="true" (remove)="product.removeTag(tag)">
 | 
			
		||||
                                            {{tag}}
 | 
			
		||||
                                            <mat-icon matChipRemove>cancel</mat-icon>
 | 
			
		||||
                                        </mat-chip>
 | 
			
		||||
                                    </mat-chip-list>
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           matChipInputAddOnBlur="true"
 | 
			
		||||
                                           (matChipInputTokenEnd)="product.addTag($event)"
 | 
			
		||||
                                           placeholder="Add tag..."
 | 
			
		||||
                                           [matChipInputFor]="tagList"/>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </mat-tab>
 | 
			
		||||
 | 
			
		||||
                        <mat-tab label="Product Images">
 | 
			
		||||
                            <div class="tab-content p-24" fusePerfectScrollbar>
 | 
			
		||||
                                <div fxLayout="row" fxLayoutAlign="start start" fxLayoutWrap>
 | 
			
		||||
 | 
			
		||||
                                    <div *ngIf="product.images.length === 0"
 | 
			
		||||
                                         class="product-image" fxlayout="row" fxLayoutAlign="center center">
 | 
			
		||||
                                        <img class="media" [src]="'assets/images/ecommerce/product-image-placeholder.png'">
 | 
			
		||||
                                    </div>
 | 
			
		||||
 | 
			
		||||
                                    <div *ngFor="let image of product.images">
 | 
			
		||||
                                        <div *ngIf="product.images.length > 0"
 | 
			
		||||
                                             class="product-image" fxlayout="row" fxLayoutAlign="center center">
 | 
			
		||||
                                            <img class="media" [src]="image.url">
 | 
			
		||||
                                        </div>
 | 
			
		||||
                                    </div>
 | 
			
		||||
                                </div>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </mat-tab>
 | 
			
		||||
 | 
			
		||||
                        <mat-tab label="Pricing">
 | 
			
		||||
                            <div class="tab-content p-24" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="priceTaxExcl"
 | 
			
		||||
                                           formControlName="priceTaxExcl"
 | 
			
		||||
                                           placeholder="Tax Excluded Price" type="number">
 | 
			
		||||
                                    <span matPrefix>$ </span>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="priceTaxIncl"
 | 
			
		||||
                                           formControlName="priceTaxIncl"
 | 
			
		||||
                                           placeholder="Tax Included Price" type="number">
 | 
			
		||||
                                    <span matPrefix>$ </span>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="taxRate"
 | 
			
		||||
                                           formControlName="taxRate"
 | 
			
		||||
                                           placeholder="Tax Rate" type="number">
 | 
			
		||||
                                    <span matPrefix>%</span>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="comparedPrice"
 | 
			
		||||
                                           formControlName="comparedPrice"
 | 
			
		||||
                                           placeholder="Compared Price" type="number">
 | 
			
		||||
                                    <span matPrefix>$ </span>
 | 
			
		||||
                                    <mat-hint align="start">Add a compare price to show next to the real price</mat-hint>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </mat-tab>
 | 
			
		||||
 | 
			
		||||
                        <mat-tab label="Inventory">
 | 
			
		||||
                            <div class="tab-content p-24" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="sku"
 | 
			
		||||
                                           formControlName="sku"
 | 
			
		||||
                                           placeholder="SKU">
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="quantity"
 | 
			
		||||
                                           formControlName="quantity"
 | 
			
		||||
                                           placeholder="Quantity" type="number">
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </mat-tab>
 | 
			
		||||
 | 
			
		||||
                        <mat-tab label="Shipping">
 | 
			
		||||
                            <div class="tab-content p-24" fusePerfectScrollbar fxLayout="column">
 | 
			
		||||
 | 
			
		||||
                                <div class="py-16" fxFlex="1 0 auto" fxLayout="row">
 | 
			
		||||
                                    <mat-form-field fxFlex>
 | 
			
		||||
                                        <input matInput
 | 
			
		||||
                                               name="Width"
 | 
			
		||||
                                               formControlName="width"
 | 
			
		||||
                                               placeholder="Width">
 | 
			
		||||
                                    </mat-form-field>
 | 
			
		||||
                                    <mat-form-field fxFlex>
 | 
			
		||||
                                        <input matInput
 | 
			
		||||
                                               name="Height"
 | 
			
		||||
                                               formControlName="height"
 | 
			
		||||
                                               placeholder="Height">
 | 
			
		||||
                                    </mat-form-field>
 | 
			
		||||
                                    <mat-form-field fxFlex>
 | 
			
		||||
                                        <input matInput
 | 
			
		||||
                                               name="Depth"
 | 
			
		||||
                                               formControlName="depth"
 | 
			
		||||
                                               placeholder="Depth">
 | 
			
		||||
                                    </mat-form-field>
 | 
			
		||||
                                </div>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="Weight"
 | 
			
		||||
                                           formControlName="weight"
 | 
			
		||||
                                           placeholder="Weight">
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
 | 
			
		||||
                                <mat-form-field class="w-100-p">
 | 
			
		||||
                                    <input matInput
 | 
			
		||||
                                           name="extraShippingFee"
 | 
			
		||||
                                           formControlName="extraShippingFee"
 | 
			
		||||
                                           placeholder="Extra Shipping Fee" type="number">
 | 
			
		||||
                                    <span matPrefix>$ </span>
 | 
			
		||||
                                </mat-form-field>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </mat-tab>
 | 
			
		||||
 | 
			
		||||
                    </mat-tab-group>
 | 
			
		||||
                </form>
 | 
			
		||||
 | 
			
		||||
            </div>
 | 
			
		||||
            <!-- / CONTENT -->
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / CONTENT CARD -->
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- / CENTER -->
 | 
			
		||||
</div>
 | 
			
		||||
@ -0,0 +1,57 @@
 | 
			
		||||
#product {
 | 
			
		||||
 | 
			
		||||
    .header {
 | 
			
		||||
 | 
			
		||||
        .product-image {
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
            width: 56px;
 | 
			
		||||
            height: 56px;
 | 
			
		||||
            border: 3px solid rgba(0, 0, 0, 0.12);
 | 
			
		||||
 | 
			
		||||
            img {
 | 
			
		||||
                height: 100%;
 | 
			
		||||
                width: auto;
 | 
			
		||||
                max-width: none;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .subtitle {
 | 
			
		||||
            margin: 6px 0 0 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .content {
 | 
			
		||||
 | 
			
		||||
        .mat-tab-group,
 | 
			
		||||
        .mat-tab-body-wrapper,
 | 
			
		||||
        .tab-content{
 | 
			
		||||
            flex: 1 1 auto;
 | 
			
		||||
            max-width: 100%;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-tab-body-content {
 | 
			
		||||
            display: flex;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-tab-label {
 | 
			
		||||
            height: 64px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .product-image {
 | 
			
		||||
            overflow: hidden;
 | 
			
		||||
            width: 128px;
 | 
			
		||||
            height: 128px;
 | 
			
		||||
            margin-right: 16px;
 | 
			
		||||
            margin-bottom: 16px;
 | 
			
		||||
            border: 3px solid rgba(0, 0, 0, 0.12);
 | 
			
		||||
 | 
			
		||||
            img {
 | 
			
		||||
                height: 100%;
 | 
			
		||||
                width: auto;
 | 
			
		||||
                max-width: none;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,132 @@
 | 
			
		||||
import { Component, ElementRef, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
 | 
			
		||||
import { EcommerceProductService } from './product.service';
 | 
			
		||||
import { fuseAnimations } from '../../../../../core/animations';
 | 
			
		||||
import 'rxjs/add/operator/startWith';
 | 
			
		||||
import 'rxjs/add/observable/merge';
 | 
			
		||||
import 'rxjs/add/operator/map';
 | 
			
		||||
import 'rxjs/add/operator/debounceTime';
 | 
			
		||||
import 'rxjs/add/operator/distinctUntilChanged';
 | 
			
		||||
import 'rxjs/add/observable/fromEvent';
 | 
			
		||||
import { Subscription } from 'rxjs/Subscription';
 | 
			
		||||
import { Product } from './product.model';
 | 
			
		||||
import { FormBuilder, FormGroup } from '@angular/forms';
 | 
			
		||||
import { FuseUtils } from '../../../../../core/fuseUtils';
 | 
			
		||||
import { MatSnackBar } from '@angular/material';
 | 
			
		||||
import { Location } from '@angular/common';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector     : 'fuse-e-commerce-product',
 | 
			
		||||
    templateUrl  : './product.component.html',
 | 
			
		||||
    styleUrls    : ['./product.component.scss'],
 | 
			
		||||
    encapsulation: ViewEncapsulation.None,
 | 
			
		||||
    animations   : fuseAnimations
 | 
			
		||||
})
 | 
			
		||||
export class FuseEcommerceProductComponent implements OnInit, OnDestroy
 | 
			
		||||
{
 | 
			
		||||
    product = new Product();
 | 
			
		||||
    onProductChanged: Subscription;
 | 
			
		||||
    pageType: string;
 | 
			
		||||
    productForm: FormGroup;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private productService: EcommerceProductService,
 | 
			
		||||
        private formBuilder: FormBuilder,
 | 
			
		||||
        public snackBar: MatSnackBar,
 | 
			
		||||
        private location: Location
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ngOnInit()
 | 
			
		||||
    {
 | 
			
		||||
        // Subscribe to update product on changes
 | 
			
		||||
        this.onProductChanged =
 | 
			
		||||
            this.productService.onProductChanged
 | 
			
		||||
                .subscribe(product => {
 | 
			
		||||
 | 
			
		||||
                    if ( product )
 | 
			
		||||
                    {
 | 
			
		||||
                        this.product = new Product(product);
 | 
			
		||||
                        this.pageType = 'edit';
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        this.pageType = 'new';
 | 
			
		||||
                        this.product = new Product();
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    this.productForm = this.createProductForm();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    createProductForm()
 | 
			
		||||
    {
 | 
			
		||||
        return this.formBuilder.group({
 | 
			
		||||
            id              : [this.product.id],
 | 
			
		||||
            name            : [this.product.name],
 | 
			
		||||
            handle          : [this.product.handle],
 | 
			
		||||
            description     : [this.product.description],
 | 
			
		||||
            categories      : [this.product.categories],
 | 
			
		||||
            tags            : [this.product.tags],
 | 
			
		||||
            images          : [this.product.images],
 | 
			
		||||
            priceTaxExcl    : [this.product.priceTaxExcl],
 | 
			
		||||
            priceTaxIncl    : [this.product.priceTaxIncl],
 | 
			
		||||
            taxRate         : [this.product.taxRate],
 | 
			
		||||
            comparedPrice   : [this.product.comparedPrice],
 | 
			
		||||
            quantity        : [this.product.quantity],
 | 
			
		||||
            sku             : [this.product.sku],
 | 
			
		||||
            width           : [this.product.width],
 | 
			
		||||
            height          : [this.product.height],
 | 
			
		||||
            depth           : [this.product.depth],
 | 
			
		||||
            weight          : [this.product.weight],
 | 
			
		||||
            extraShippingFee: [this.product.extraShippingFee],
 | 
			
		||||
            active          : [this.product.active]
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    saveProduct()
 | 
			
		||||
    {
 | 
			
		||||
        const data = this.productForm.getRawValue();
 | 
			
		||||
        data.handle = FuseUtils.handleize(data.name);
 | 
			
		||||
        this.productService.saveProduct(data)
 | 
			
		||||
            .then(() => {
 | 
			
		||||
 | 
			
		||||
                // Trigger the subscription with new data
 | 
			
		||||
                this.productService.onProductChanged.next(data);
 | 
			
		||||
 | 
			
		||||
                // Show the success message
 | 
			
		||||
                this.snackBar.open('Product saved', 'OK', {
 | 
			
		||||
                    verticalPosition: 'top',
 | 
			
		||||
                    duration        : 2000
 | 
			
		||||
                });
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addProduct()
 | 
			
		||||
    {
 | 
			
		||||
        const data = this.productForm.getRawValue();
 | 
			
		||||
        data.handle = FuseUtils.handleize(data.name);
 | 
			
		||||
        this.productService.addProduct(data)
 | 
			
		||||
            .then(() => {
 | 
			
		||||
 | 
			
		||||
                // Trigger the subscription with new data
 | 
			
		||||
                this.productService.onProductChanged.next(data);
 | 
			
		||||
 | 
			
		||||
                // Show the success message
 | 
			
		||||
                this.snackBar.open('Product added', 'OK', {
 | 
			
		||||
                    verticalPosition: 'top',
 | 
			
		||||
                    duration        : 2000
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                // Change the location with new one
 | 
			
		||||
                this.location.go('apps/e-commerce/products/' + this.product.id + '/' + this.product.handle);
 | 
			
		||||
            });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ngOnDestroy()
 | 
			
		||||
    {
 | 
			
		||||
        this.onProductChanged.unsubscribe();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										110
									
								
								src/app/main/content/apps/e-commerce/product/product.model.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										110
									
								
								src/app/main/content/apps/e-commerce/product/product.model.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,110 @@
 | 
			
		||||
import { FuseUtils } from '../../../../../core/fuseUtils';
 | 
			
		||||
import { MatChipInputEvent } from '@angular/material';
 | 
			
		||||
 | 
			
		||||
export class Product
 | 
			
		||||
{
 | 
			
		||||
    id: string;
 | 
			
		||||
    name: string;
 | 
			
		||||
    handle: string;
 | 
			
		||||
    description: string;
 | 
			
		||||
    categories: string[];
 | 
			
		||||
    tags: string[];
 | 
			
		||||
    images: {
 | 
			
		||||
        default: boolean,
 | 
			
		||||
        id: string,
 | 
			
		||||
        url: string,
 | 
			
		||||
        type: string
 | 
			
		||||
    }[];
 | 
			
		||||
    priceTaxExcl: number;
 | 
			
		||||
    priceTaxIncl: number;
 | 
			
		||||
    taxRate: number;
 | 
			
		||||
    comparedPrice: number;
 | 
			
		||||
    quantity: number;
 | 
			
		||||
    sku: string;
 | 
			
		||||
    width: string;
 | 
			
		||||
    height: string;
 | 
			
		||||
    depth: string;
 | 
			
		||||
    weight: string;
 | 
			
		||||
    extraShippingFee: number;
 | 
			
		||||
    active: boolean;
 | 
			
		||||
 | 
			
		||||
    constructor(product?)
 | 
			
		||||
    {
 | 
			
		||||
        product = product || {};
 | 
			
		||||
        this.id = product.id || FuseUtils.generateGUID();
 | 
			
		||||
        this.name = product.name || '';
 | 
			
		||||
        this.handle = product.handle || FuseUtils.handleize(this.name);
 | 
			
		||||
        this.description = product.description || '';
 | 
			
		||||
        this.categories = product.categories || [];
 | 
			
		||||
        this.tags = product.tags || [];
 | 
			
		||||
        this.images = product.images || [];
 | 
			
		||||
        this.priceTaxExcl = product.priceTaxExcl || 0;
 | 
			
		||||
        this.priceTaxIncl = product.priceTaxIncl || 0;
 | 
			
		||||
        this.taxRate = product.taxRate || 0;
 | 
			
		||||
        this.comparedPrice = product.comparedPrice || 0;
 | 
			
		||||
        this.quantity = product.quantity || 0;
 | 
			
		||||
        this.sku = product.sku || 0;
 | 
			
		||||
        this.width = product.width || 0;
 | 
			
		||||
        this.height = product.height || 0;
 | 
			
		||||
        this.depth = product.depth || 0;
 | 
			
		||||
        this.weight = product.weight || 0;
 | 
			
		||||
        this.extraShippingFee = product.extraShippingFee || 0;
 | 
			
		||||
        this.active = product.active || true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addCategory(event: MatChipInputEvent): void
 | 
			
		||||
    {
 | 
			
		||||
        const input = event.input;
 | 
			
		||||
        const value = event.value;
 | 
			
		||||
 | 
			
		||||
        // Add category
 | 
			
		||||
        if ( value )
 | 
			
		||||
        {
 | 
			
		||||
            this.categories.push(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Reset the input value
 | 
			
		||||
        if ( input )
 | 
			
		||||
        {
 | 
			
		||||
            input.value = '';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    removeCategory(category)
 | 
			
		||||
    {
 | 
			
		||||
        const index = this.categories.indexOf(category);
 | 
			
		||||
 | 
			
		||||
        if ( index >= 0 )
 | 
			
		||||
        {
 | 
			
		||||
            this.categories.splice(index, 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addTag(event: MatChipInputEvent): void
 | 
			
		||||
    {
 | 
			
		||||
        const input = event.input;
 | 
			
		||||
        const value = event.value;
 | 
			
		||||
 | 
			
		||||
        // Add tag
 | 
			
		||||
        if ( value )
 | 
			
		||||
        {
 | 
			
		||||
            this.tags.push(value);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Reset the input value
 | 
			
		||||
        if ( input )
 | 
			
		||||
        {
 | 
			
		||||
            input.value = '';
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    removeTag(tag)
 | 
			
		||||
    {
 | 
			
		||||
        const index = this.tags.indexOf(tag);
 | 
			
		||||
 | 
			
		||||
        if ( index >= 0 )
 | 
			
		||||
        {
 | 
			
		||||
            this.tags.splice(index, 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,83 @@
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
 | 
			
		||||
import { Observable } from 'rxjs/Observable';
 | 
			
		||||
import { HttpClient } from '@angular/common/http';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class EcommerceProductService implements Resolve<any>
 | 
			
		||||
{
 | 
			
		||||
    routeParams: any;
 | 
			
		||||
    product: any;
 | 
			
		||||
    onProductChanged: BehaviorSubject<any> = new BehaviorSubject({});
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private http: HttpClient
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Resolve
 | 
			
		||||
     * @param {ActivatedRouteSnapshot} route
 | 
			
		||||
     * @param {RouterStateSnapshot} state
 | 
			
		||||
     * @returns {Observable<any> | Promise<any> | any}
 | 
			
		||||
     */
 | 
			
		||||
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        this.routeParams = route.params;
 | 
			
		||||
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
            Promise.all([
 | 
			
		||||
                this.getProduct()
 | 
			
		||||
            ]).then(
 | 
			
		||||
                () => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                },
 | 
			
		||||
                reject
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getProduct(): Promise<any>
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            if ( this.routeParams.id === 'new' )
 | 
			
		||||
            {
 | 
			
		||||
                this.onProductChanged.next(false);
 | 
			
		||||
                resolve(false);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                this.http.get('api/e-commerce-products/' + this.routeParams.id)
 | 
			
		||||
                    .subscribe((response: any) => {
 | 
			
		||||
                        this.product = response;
 | 
			
		||||
                        this.onProductChanged.next(this.product);
 | 
			
		||||
                        resolve(response);
 | 
			
		||||
                    }, reject);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    saveProduct(product)
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.post('api/e-commerce-products/' + product.id, product)
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    addProduct(product)
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.post('api/e-commerce-products/', product)
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,145 @@
 | 
			
		||||
<div id="products" class="page-layout carded fullwidth" fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
    <!-- TOP BACKGROUND -->
 | 
			
		||||
    <div class="top-bg mat-accent-bg"></div>
 | 
			
		||||
    <!-- / TOP BACKGROUND -->
 | 
			
		||||
 | 
			
		||||
    <!-- CENTER -->
 | 
			
		||||
    <div class="center">
 | 
			
		||||
 | 
			
		||||
        <!-- HEADER -->
 | 
			
		||||
        <div class="header white-fg"
 | 
			
		||||
             fxLayout="column" fxLayoutAlign="center center"
 | 
			
		||||
             fxLayout.gt-xs="row" fxLayoutAlign.gt-xs="space-between center">
 | 
			
		||||
 | 
			
		||||
            <!-- APP TITLE -->
 | 
			
		||||
            <div class="logo my-12 m-sm-0"
 | 
			
		||||
                 fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                <mat-icon class="logo-icon mr-16" *fuseIfOnDom [@animate]="{value:'*',params:{delay:'50ms',scale:'0.2'}}">shopping_basket</mat-icon>
 | 
			
		||||
                <span class="logo-text h1" *fuseIfOnDom [@animate]="{value:'*',params:{delay:'100ms',x:'-25px'}}">Products</span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <!-- / APP TITLE -->
 | 
			
		||||
 | 
			
		||||
            <!-- SEARCH -->
 | 
			
		||||
            <div class="search-input-wrapper mx-12 m-md-0"
 | 
			
		||||
                 fxFlex="1 0 auto" fxLayout="row" fxLayoutAlign="start center">
 | 
			
		||||
                <label for="search" class="mr-8">
 | 
			
		||||
                    <mat-icon class="secondary-text">search</mat-icon>
 | 
			
		||||
                </label>
 | 
			
		||||
                <mat-form-field floatPlaceholder="never" fxFlex="1 0 auto">
 | 
			
		||||
                    <input id="search" matInput #filter placeholder="Search">
 | 
			
		||||
                </mat-form-field>
 | 
			
		||||
            </div>
 | 
			
		||||
            <!-- / SEARCH -->
 | 
			
		||||
 | 
			
		||||
            <button mat-raised-button
 | 
			
		||||
                    [routerLink]="'/apps/e-commerce/products/new'"
 | 
			
		||||
                    class="add-product-button mat-white-bg my-12 mt-sm-0">
 | 
			
		||||
                <span>ADD NEW PRODUCT</span>
 | 
			
		||||
            </button>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / HEADER -->
 | 
			
		||||
 | 
			
		||||
        <!-- CONTENT CARD -->
 | 
			
		||||
        <div class="content-card mat-white-bg">
 | 
			
		||||
 | 
			
		||||
            <mat-table class="products-table"
 | 
			
		||||
                       #table [dataSource]="dataSource"
 | 
			
		||||
                       matSort
 | 
			
		||||
                       [@animateStagger]="{value:'50'}"
 | 
			
		||||
                       fusePerfectScrollbar>
 | 
			
		||||
 | 
			
		||||
                <!-- ID Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="id">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header>ID</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let product">
 | 
			
		||||
                        <p class="text-truncate">{{product.id}}</p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Image Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="image">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef></mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let product">
 | 
			
		||||
                        <img class="product-image"
 | 
			
		||||
                             *ngIf="product.images[0]" [alt]="product.name"
 | 
			
		||||
                             [src]="product.images[0].url"/>
 | 
			
		||||
                        <img *ngIf="!product.images[0]" [src]="'assets/images/ecommerce/product-image-placeholder.png'">
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Name Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="name">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header>Name</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let product">
 | 
			
		||||
                        <p class="text-truncate">{{product.name}}</p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Category Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="category">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef fxHide mat-sort-header fxShow.gt-md>Category</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let product" fxHide fxShow.gt-md>
 | 
			
		||||
                        <p class="category text-truncate">
 | 
			
		||||
                            {{product.categories[0]}}
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Price Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="price">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header fxHide fxShow.gt-xs>Price</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let product" fxHide fxShow.gt-xs>
 | 
			
		||||
                        <p class="price text-truncate">
 | 
			
		||||
                            {{product.priceTaxIncl | currency:'USD':true}}
 | 
			
		||||
                        </p>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Quantity Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="quantity">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header fxHide fxShow.gt-sm>Quantity</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let product" fxHide fxShow.gt-sm>
 | 
			
		||||
 | 
			
		||||
                        <span class="quantity-indicator text-truncate"
 | 
			
		||||
                              [ngClass]="{'mat-red-500-bg':product.quantity <= 5, 'mat-amber-500-bg':product.quantity > 5 && product.quantity <= 25,'mat-green-600-bg':product.quantity > 25}">
 | 
			
		||||
                        </span>
 | 
			
		||||
                        <span>
 | 
			
		||||
                            {{product.quantity}}
 | 
			
		||||
                        </span>
 | 
			
		||||
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <!-- Active Column -->
 | 
			
		||||
                <ng-container cdkColumnDef="active">
 | 
			
		||||
                    <mat-header-cell *cdkHeaderCellDef mat-sort-header fxHide fxShow.gt-xs>Active</mat-header-cell>
 | 
			
		||||
                    <mat-cell *cdkCellDef="let product" fxHide fxShow.gt-xs>
 | 
			
		||||
                        <mat-icon *ngIf="product.active" class="active-icon mat-green-600-bg s-16">check</mat-icon>
 | 
			
		||||
                        <mat-icon *ngIf="!product.active" class="active-icon mat-red-500-bg s-16">close</mat-icon>
 | 
			
		||||
                    </mat-cell>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
 | 
			
		||||
                <mat-header-row *cdkHeaderRowDef="displayedColumns"></mat-header-row>
 | 
			
		||||
 | 
			
		||||
                <mat-row *cdkRowDef="let product; columns: displayedColumns;"
 | 
			
		||||
                         class="product"
 | 
			
		||||
                         matRipple
 | 
			
		||||
                         [routerLink]="'/apps/e-commerce/products/'+product.id+'/'+product.handle">
 | 
			
		||||
                </mat-row>
 | 
			
		||||
 | 
			
		||||
            </mat-table>
 | 
			
		||||
 | 
			
		||||
            <mat-paginator #paginator
 | 
			
		||||
                           [length]="dataSource.filteredData.length"
 | 
			
		||||
                           [pageIndex]="0"
 | 
			
		||||
                           [pageSize]="10"
 | 
			
		||||
                           [pageSizeOptions]="[5, 10, 25, 100]">
 | 
			
		||||
            </mat-paginator>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
        <!-- / CONTENT CARD -->
 | 
			
		||||
    </div>
 | 
			
		||||
    <!-- / CENTER -->
 | 
			
		||||
</div>
 | 
			
		||||
@ -0,0 +1,80 @@
 | 
			
		||||
@import "src/app/core/scss/fuse";
 | 
			
		||||
 | 
			
		||||
:host {
 | 
			
		||||
 | 
			
		||||
    .header {
 | 
			
		||||
 | 
			
		||||
        .search-input-wrapper {
 | 
			
		||||
            max-width: 480px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @include media-breakpoint-down(xs) {
 | 
			
		||||
            height: 176px !important;
 | 
			
		||||
            min-height: 176px !important;
 | 
			
		||||
            max-height: 176px !important;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .top-bg {
 | 
			
		||||
        @include media-breakpoint-down(xs) {
 | 
			
		||||
            height: 240px;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    .products-table {
 | 
			
		||||
        flex: 1 1 auto;
 | 
			
		||||
        border-bottom: 1px solid rgba(0, 0, 0, .12);
 | 
			
		||||
 | 
			
		||||
        .mat-header-row {
 | 
			
		||||
            min-height: 64px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .product {
 | 
			
		||||
            position: relative;
 | 
			
		||||
            cursor: pointer;
 | 
			
		||||
            height: 84px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-cell {
 | 
			
		||||
            min-width: 0;
 | 
			
		||||
            display: flex;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-column-id {
 | 
			
		||||
            flex: 0 1 84px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-column-image {
 | 
			
		||||
            flex: 0 1 84px;
 | 
			
		||||
 | 
			
		||||
            .product-image {
 | 
			
		||||
                width: 52px;
 | 
			
		||||
                height: 52px;
 | 
			
		||||
                border: 1px solid rgba(0, 0, 0, .12);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .mat-column-buttons {
 | 
			
		||||
            flex: 0 1 80px;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .quantity-indicator {
 | 
			
		||||
            display: inline-block;
 | 
			
		||||
            vertical-align: middle;
 | 
			
		||||
            width: 8px;
 | 
			
		||||
            height: 8px;
 | 
			
		||||
            border-radius: 4px;
 | 
			
		||||
            margin-right: 8px;
 | 
			
		||||
 | 
			
		||||
            & + span {
 | 
			
		||||
                display: inline-block;
 | 
			
		||||
                vertical-align: middle;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        .active-icon {
 | 
			
		||||
            border-radius: 50%;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,165 @@
 | 
			
		||||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
 | 
			
		||||
import { EcommerceProductsService } from './products.service';
 | 
			
		||||
import { DataSource } from '@angular/cdk/collections';
 | 
			
		||||
import { Observable } from 'rxjs/Observable';
 | 
			
		||||
import { fuseAnimations } from '../../../../../core/animations';
 | 
			
		||||
import { MatPaginator, MatSort } from '@angular/material';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 | 
			
		||||
import 'rxjs/add/operator/startWith';
 | 
			
		||||
import 'rxjs/add/observable/merge';
 | 
			
		||||
import 'rxjs/add/operator/map';
 | 
			
		||||
import 'rxjs/add/operator/debounceTime';
 | 
			
		||||
import 'rxjs/add/operator/distinctUntilChanged';
 | 
			
		||||
import 'rxjs/add/observable/fromEvent';
 | 
			
		||||
import { FuseUtils } from '../../../../../core/fuseUtils';
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
    selector   : 'fuse-e-commerce-products',
 | 
			
		||||
    templateUrl: './products.component.html',
 | 
			
		||||
    styleUrls  : ['./products.component.scss'],
 | 
			
		||||
    animations : fuseAnimations
 | 
			
		||||
})
 | 
			
		||||
export class FuseEcommerceProductsComponent implements OnInit
 | 
			
		||||
{
 | 
			
		||||
    dataSource: FilesDataSource | null;
 | 
			
		||||
    displayedColumns = ['id', 'image', 'name', 'category', 'price', 'quantity', 'active'];
 | 
			
		||||
 | 
			
		||||
    @ViewChild(MatPaginator) paginator: MatPaginator;
 | 
			
		||||
    @ViewChild('filter') filter: ElementRef;
 | 
			
		||||
    @ViewChild(MatSort) sort: MatSort;
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private productsService: EcommerceProductsService
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ngOnInit()
 | 
			
		||||
    {
 | 
			
		||||
        this.dataSource = new FilesDataSource(this.productsService, this.paginator, this.sort);
 | 
			
		||||
        Observable.fromEvent(this.filter.nativeElement, 'keyup')
 | 
			
		||||
                  .debounceTime(150)
 | 
			
		||||
                  .distinctUntilChanged()
 | 
			
		||||
                  .subscribe(() => {
 | 
			
		||||
                      if ( !this.dataSource )
 | 
			
		||||
                      {
 | 
			
		||||
                          return;
 | 
			
		||||
                      }
 | 
			
		||||
                      this.dataSource.filter = this.filter.nativeElement.value;
 | 
			
		||||
                  });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class FilesDataSource extends DataSource<any>
 | 
			
		||||
{
 | 
			
		||||
    _filterChange = new BehaviorSubject('');
 | 
			
		||||
    _filteredDataChange = new BehaviorSubject('');
 | 
			
		||||
 | 
			
		||||
    get filteredData(): any
 | 
			
		||||
    {
 | 
			
		||||
        return this._filteredDataChange.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set filteredData(value: any)
 | 
			
		||||
    {
 | 
			
		||||
        this._filteredDataChange.next(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    get filter(): string
 | 
			
		||||
    {
 | 
			
		||||
        return this._filterChange.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    set filter(filter: string)
 | 
			
		||||
    {
 | 
			
		||||
        this._filterChange.next(filter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private productsService: EcommerceProductsService,
 | 
			
		||||
        private _paginator: MatPaginator,
 | 
			
		||||
        private _sort: MatSort
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
        super();
 | 
			
		||||
        this.filteredData = this.productsService.products;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Connect function called by the table to retrieve one stream containing the data to render. */
 | 
			
		||||
    connect(): Observable<any[]>
 | 
			
		||||
    {
 | 
			
		||||
        const displayDataChanges = [
 | 
			
		||||
            this.productsService.onProductsChanged,
 | 
			
		||||
            this._paginator.page,
 | 
			
		||||
            this._filterChange,
 | 
			
		||||
            this._sort.sortChange
 | 
			
		||||
        ];
 | 
			
		||||
 | 
			
		||||
        return Observable.merge(...displayDataChanges).map(() => {
 | 
			
		||||
            let data = this.productsService.products.slice();
 | 
			
		||||
 | 
			
		||||
            data = this.filterData(data);
 | 
			
		||||
 | 
			
		||||
            this.filteredData = [...data];
 | 
			
		||||
 | 
			
		||||
            data = this.sortData(data);
 | 
			
		||||
 | 
			
		||||
            // Grab the page's slice of data.
 | 
			
		||||
            const startIndex = this._paginator.pageIndex * this._paginator.pageSize;
 | 
			
		||||
            return data.splice(startIndex, this._paginator.pageSize);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    filterData(data)
 | 
			
		||||
    {
 | 
			
		||||
        if ( !this.filter )
 | 
			
		||||
        {
 | 
			
		||||
            return data;
 | 
			
		||||
        }
 | 
			
		||||
        return FuseUtils.filterArrayByString(data, this.filter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sortData(data): any[]
 | 
			
		||||
    {
 | 
			
		||||
        if ( !this._sort.active || this._sort.direction === '' )
 | 
			
		||||
        {
 | 
			
		||||
            return data;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return data.sort((a, b) => {
 | 
			
		||||
            let propertyA: number | string = '';
 | 
			
		||||
            let propertyB: number | string = '';
 | 
			
		||||
 | 
			
		||||
            switch ( this._sort.active )
 | 
			
		||||
            {
 | 
			
		||||
                case 'id':
 | 
			
		||||
                    [propertyA, propertyB] = [a.id, b.id];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'name':
 | 
			
		||||
                    [propertyA, propertyB] = [a.name, b.name];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'categories':
 | 
			
		||||
                    [propertyA, propertyB] = [a.categories[0], b.categories[0]];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'price':
 | 
			
		||||
                    [propertyA, propertyB] = [a.priceTaxIncl, b.priceTaxIncl];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'quantity':
 | 
			
		||||
                    [propertyA, propertyB] = [a.quantity, b.quantity];
 | 
			
		||||
                    break;
 | 
			
		||||
                case 'active':
 | 
			
		||||
                    [propertyA, propertyB] = [a.active, b.active];
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const valueA = isNaN(+propertyA) ? propertyA : +propertyA;
 | 
			
		||||
            const valueB = isNaN(+propertyB) ? propertyB : +propertyB;
 | 
			
		||||
 | 
			
		||||
            return (valueA < valueB ? -1 : 1) * (this._sort.direction === 'asc' ? 1 : -1);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    disconnect()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,52 @@
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { ActivatedRouteSnapshot, Resolve, RouterStateSnapshot } from '@angular/router';
 | 
			
		||||
import { Observable } from 'rxjs/Observable';
 | 
			
		||||
import { HttpClient } from '@angular/common/http';
 | 
			
		||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class EcommerceProductsService implements Resolve<any>
 | 
			
		||||
{
 | 
			
		||||
    products: any[];
 | 
			
		||||
    onProductsChanged: BehaviorSubject<any> = new BehaviorSubject({});
 | 
			
		||||
 | 
			
		||||
    constructor(
 | 
			
		||||
        private http: HttpClient
 | 
			
		||||
    )
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Resolve
 | 
			
		||||
     * @param {ActivatedRouteSnapshot} route
 | 
			
		||||
     * @param {RouterStateSnapshot} state
 | 
			
		||||
     * @returns {Observable<any> | Promise<any> | any}
 | 
			
		||||
     */
 | 
			
		||||
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | Promise<any> | any
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
 | 
			
		||||
            Promise.all([
 | 
			
		||||
                this.getProducts()
 | 
			
		||||
            ]).then(
 | 
			
		||||
                () => {
 | 
			
		||||
                    resolve();
 | 
			
		||||
                },
 | 
			
		||||
                reject
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getProducts(): Promise<any>
 | 
			
		||||
    {
 | 
			
		||||
        return new Promise((resolve, reject) => {
 | 
			
		||||
            this.http.get('api/e-commerce-products')
 | 
			
		||||
                .subscribe((response: any) => {
 | 
			
		||||
                    this.products = response;
 | 
			
		||||
                    this.onProductsChanged.next(this.products);
 | 
			
		||||
                    resolve(response);
 | 
			
		||||
                }, reject);
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -32,6 +32,32 @@ export class NavigationModel
 | 
			
		||||
                        'icon' : 'today',
 | 
			
		||||
                        'url'  : '/apps/calendar'
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        'id'      : 'e-commerce',
 | 
			
		||||
                        'title'   : 'E-Commerce',
 | 
			
		||||
                        'type'    : 'collapse',
 | 
			
		||||
                        'icon'    : 'shopping_cart',
 | 
			
		||||
                        'children': [
 | 
			
		||||
                            {
 | 
			
		||||
                                'id'   : 'dashboard',
 | 
			
		||||
                                'title': 'Dashboard',
 | 
			
		||||
                                'type' : 'item',
 | 
			
		||||
                                'url'  : '/apps/e-commerce/dashboard'
 | 
			
		||||
                            },
 | 
			
		||||
                            {
 | 
			
		||||
                                'id'   : 'dashboard',
 | 
			
		||||
                                'title': 'Products',
 | 
			
		||||
                                'type' : 'item',
 | 
			
		||||
                                'url'  : '/apps/e-commerce/products'
 | 
			
		||||
                            },
 | 
			
		||||
                            {
 | 
			
		||||
                                'id'   : 'dashboard',
 | 
			
		||||
                                'title': 'Orders',
 | 
			
		||||
                                'type' : 'item',
 | 
			
		||||
                                'url'  : '/apps/e-commerce/orders'
 | 
			
		||||
                            }
 | 
			
		||||
                        ]
 | 
			
		||||
                    },
 | 
			
		||||
                    {
 | 
			
		||||
                        'id'   : 'mail',
 | 
			
		||||
                        'title': 'Mail',
 | 
			
		||||
@ -807,3 +833,4 @@ export class NavigationModel
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user