"src/favicon.ico"
],
"styles": [
- "node_modules/bootstrap/dist/css/bootstrap.css",
- "node_modules/ng2-toastr/bundles/ng2-toastr.min.css",
- "node_modules/fork-awesome/css/fork-awesome.css",
- "node_modules/awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css",
+ "node_modules/ngx-toastr/toastr.css",
"node_modules/ngx-bootstrap/datepicker/bs-datepicker.css",
"src/styles.scss",
- "src/vendor.overrides.scss",
+ "src/styles/vendor.overrides.scss",
"node_modules/ng2-tree/styles.css"
],
"scripts": [
"node_modules/chart.js/dist/Chart.bundle.js"
- ]
+ ],
+ "stylePreprocessorOptions": {
+ "includePaths": [
+ "src/styles",
+ "src"
+ ]
+ }
},
"configurations": {
"production": {
"requires": {
"tslib": "^1.9.0"
}
- },
- "semver": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
- "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- },
- "source-map-support": {
- "version": "0.5.10",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
- "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
- "dev": true,
- "requires": {
- "buffer-from": "^1.0.0",
- "source-map": "^0.6.0"
- }
}
}
},
"requires": {
"tslib": "^1.9.0"
}
- },
- "source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "dev": true
}
}
},
"requires": {
"tslib": "^1.9.0"
}
- },
- "source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "dev": true
}
}
},
"yargs": "9.0.1"
},
"dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
"camelcase": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
"dev": true
},
"chokidar": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.2.tgz",
- "integrity": "sha512-IwXUx0FXc5ibYmPC2XeEj5mpXoV66sR+t3jqu2NS2GYwCktt3KF1/Qqjws/NkegajBA4RbZ5+DDwlOiJsxDHEg==",
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.5.tgz",
+ "integrity": "sha512-i0TprVWp+Kj4WRPtInjexJ8Q+BqTE909VpH8xVhXrJkoc5QC8VO9TryGOqTr+2hljzc1sC62t22h5tZePodM/A==",
"dev": true,
"requires": {
"anymatch": "^2.0.0",
"normalize-path": "^3.0.0",
"path-is-absolute": "^1.0.0",
"readdirp": "^2.2.1",
- "upath": "^1.1.0"
+ "upath": "^1.1.1"
}
},
"cliui": {
},
"load-json-file": {
"version": "2.0.0",
- "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"dev": true,
"requires": {
"strip-bom": "^3.0.0"
}
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"dev": true
},
- "os-locale": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
- "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
- "dev": true,
- "requires": {
- "execa": "^0.7.0",
- "lcid": "^1.0.0",
- "mem": "^1.1.0"
- }
- },
"path-type": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
"read-pkg": "^2.0.0"
}
},
- "readdirp": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
- "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.11",
- "micromatch": "^3.1.10",
- "readable-stream": "^2.0.2"
- }
- },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
},
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
"dev": true
},
- "which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
- "dev": true
- },
- "y18n": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
- "dev": true
- },
"yargs": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz",
"minimist": "^1.2.0"
}
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"ms": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
}
}
},
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
"integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
"dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
}
}
},
"uuid": "^3.3.2"
},
"dependencies": {
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
"chokidar": {
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
"minimist": "^1.2.0"
}
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"string-length": "^2.0.0"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"source-map": "^0.6.0"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"write-file-atomic": "2.4.1"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"yargs": "10.0.3"
},
"dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
- },
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
- },
- "cliui": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
- "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
- "requires": {
- "string-width": "^1.0.1",
- "strip-ansi": "^3.0.1",
- "wrap-ansi": "^2.0.0"
- },
- "dependencies": {
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
- }
- }
- }
- },
- "os-locale": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
- "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
- "requires": {
- "execa": "^0.7.0",
- "lcid": "^1.0.0",
- "mem": "^1.1.0"
- }
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
- "which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
- },
- "y18n": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
- "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
- },
"yargs": {
"version": "10.0.3",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-10.0.3.tgz",
"y18n": "^3.2.1",
"yargs-parser": "^8.0.0"
}
- },
- "yargs-parser": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz",
- "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==",
- "requires": {
- "camelcase": "^4.1.0"
- }
}
}
},
"requires": {
"tslib": "^1.9.0"
}
- },
- "semver": {
- "version": "5.6.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
- "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
- "dev": true
- },
- "source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
- "dev": true
}
}
},
"dev": true
},
"@types/selenium-webdriver": {
- "version": "3.0.14",
- "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.14.tgz",
- "integrity": "sha512-4GbNCDs98uHCT/OMv40qQC/OpoPbYn9XdXeTiFwHBBFO6eJhYEPUu2zDKirXSbHlvDV8oZ9l8EQ+HrEx/YS9DQ==",
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-3.0.16.tgz",
+ "integrity": "sha512-lMC2G0ItF2xv4UCiwbJGbnJlIuUixHrioOhNGHSCsYCJ8l4t9hMCUimCytvFv7qy6AfSzRxhRHoGa+UqaqwyeA==",
"dev": true
},
"@types/source-list-map": {
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
- },
- "dependencies": {
- "fast-deep-equal": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
- "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
- "dev": true
- },
- "json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "dev": true
- }
}
},
"ajv-errors": {
},
"dependencies": {
"color-convert": {
- "version": "1.9.2",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.2.tgz",
- "integrity": "sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg==",
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
"dev": true,
"requires": {
- "color-name": "1.1.1"
+ "color-name": "1.1.3"
}
},
"color-name": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.1.tgz",
- "integrity": "sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok=",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
}
}
"dev": true
},
"app-root-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.1.0.tgz",
- "integrity": "sha1-mL9lmTJ+zqGZMJhm6BQDaP0uZGo=",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.2.1.tgz",
+ "integrity": "sha512-91IFKeKk7FjfmezPKkwtaRvSpnUc4gDwPAjA1YZ9Gn0q0PPeW+vbeUsZuyDwjI7+QTHhcLen2v25fi/AmhvbJA==",
"dev": true
},
"aproba": {
"optional": true
},
"asn1": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
- "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
- "dev": true
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
},
"asn1.js": {
"version": "4.10.1",
}
},
"async-each": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
- "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
"dev": true
},
"async-foreach": {
"dev": true
},
"atob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
- "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
"dev": true
},
"autoprefixer": {
}
},
"awesome-bootstrap-checkbox": {
- "version": "0.3.7",
- "resolved": "https://registry.npmjs.org/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-0.3.7.tgz",
- "integrity": "sha1-sRKXPubVv/QKshfEIBhcRwJR0OI="
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/awesome-bootstrap-checkbox/-/awesome-bootstrap-checkbox-1.0.1.tgz",
+ "integrity": "sha1-2rEBRrYAESmrCg7B5Uu3fGwwRXo="
},
"aws-sign2": {
"version": "0.7.0",
"dev": true
},
"aws4": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
- "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true
},
"babel-code-frame": {
"lodash": "^4.17.4",
"source-map": "^0.5.7",
"trim-right": "^1.0.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
}
},
"babel-helper-builder-binary-assignment-operator-visitor": {
"slash": "^2.0.0"
},
"dependencies": {
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
"slash": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
"browserslist": "^3.2.6",
"invariant": "^2.2.2",
"semver": "^5.3.0"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "3.2.8",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+ "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30000844",
+ "electron-to-chromium": "^1.3.47"
+ }
+ }
}
},
"babel-preset-jest": {
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"dev": true,
- "optional": true,
"requires": {
"tweetnacl": "^0.14.3"
}
"dev": true
},
"binary-extensions": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
- "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
"dev": true
},
"block-stream": {
"dev": true,
"requires": {
"minimist": "^1.2.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
}
},
"bluebird": {
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
"dev": true
},
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
"qs": {
"version": "6.7.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
"dev": true
},
"bootstrap": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-3.4.1.tgz",
- "integrity": "sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA=="
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.3.1.tgz",
+ "integrity": "sha512-rXqOmH1VilAt2DyPzluTi2blhk17bO7ef+zLLPlWvG494pDxcM234pJ8wTc/6R40UWizAIIMgxjvxZg5kmsbag=="
},
"brace-expansion": {
"version": "1.1.11",
"pako": "~1.0.5"
}
},
- "browserslist": {
- "version": "3.2.8",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
- "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
- "dev": true,
- "requires": {
- "caniuse-lite": "^1.0.30000844",
- "electron-to-chromium": "^1.3.47"
- }
- },
"browserstack": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.1.tgz",
- "integrity": "sha512-O8VMT64P9NOLhuIoD4YngyxBURefaSdR4QdhG8l6HZ9VxtU7jc3m6jLufFwKA5gaf7fetfB2TnRJnMxyob+heg==",
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/browserstack/-/browserstack-1.5.2.tgz",
+ "integrity": "sha512-+6AFt9HzhKykcPF79W6yjEUJcdvZOV0lIXdkORXMJftGrDl0OKWqRF4GHqpDNkxiceDT/uB7Fb/aDwktvXX7dg==",
"dev": true,
"requires": {
"https-proxy-agent": "^2.2.1"
"dev": true
},
"buffer-from": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz",
- "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"buffer-indexof": {
"ssri": "^5.2.4",
"unique-filename": "^1.1.0",
"y18n": "^4.0.0"
+ },
+ "dependencies": {
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ }
}
},
"cache-base": {
"dev": true,
"requires": {
"callsites": "^2.0.0"
- },
- "dependencies": {
- "callsites": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
- "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
- "dev": true
- }
}
},
"caller-path": {
}
},
"callsites": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.0.0.tgz",
- "integrity": "sha512-tWnkwu9YEq2uzlBDI4RcLn8jrFvF9AOi8PxDNU3hZZjJcjkcRAq3vCI+vZcg1SuxISDYe86k9VZFwAxDiJGoAw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
"dev": true
},
"camelcase": {
}
},
"caniuse-lite": {
- "version": "1.0.30000865",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000865.tgz",
- "integrity": "sha512-vs79o1mOSKRGv/1pSkp4EXgl4ZviWeYReXw60XfacPU64uQWZwJT6vZNmxRF9O+6zu71sJwMxLK5JXxbzuVrLw==",
+ "version": "1.0.30000960",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000960.tgz",
+ "integrity": "sha512-7nK5qs17icQaX6V3/RYrJkOsZyRNnroA4+ZwxaKJzIKy+crIy0Mz5CBlLySd2SNV+4nbUZeqeNfiaEieUBu3aA==",
"dev": true
},
"canonical-path": {
"dev": true
},
"chalk": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz",
- "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==",
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
"dev": true,
"requires": {
- "ansi-styles": "^3.1.0",
+ "ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
- "supports-color": "^4.0.0"
+ "supports-color": "^5.3.0"
},
"dependencies": {
- "has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
- "dev": true
- },
"supports-color": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
- "has-flag": "^2.0.0"
+ "has-flag": "^3.0.0"
}
}
}
}
},
"chartjs-color": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.2.0.tgz",
- "integrity": "sha1-hKL7dVeH7YXDndbdjHsdiEKbrq4=",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.3.0.tgz",
+ "integrity": "sha512-hEvVheqczsoHD+fZ+tfPUE+1+RbV6b+eksp2LwAhwRTVXEjCSEavvk+Hg3H6SZfGlPh/UfmWKGIvZbtobOEm3g==",
"requires": {
- "chartjs-color-string": "^0.5.0",
+ "chartjs-color-string": "^0.6.0",
"color-convert": "^0.5.3"
}
},
"chartjs-color-string": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.5.0.tgz",
- "integrity": "sha512-amWNvCOXlOUYxZVDSa0YOab5K/lmEhbFNKI55PWc4mlv28BDzA7zaoQTGxSBgJMHIW+hGX8YUrvw/FH4LyhwSQ==",
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz",
+ "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==",
"requires": {
"color-name": "^1.0.0"
}
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
- "dev": true,
- "optional": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wrap-ansi": "^2.0.0"
+ },
+ "dependencies": {
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ }
}
},
"clone": {
"sprintf-js": "^1.1.1"
},
"dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
"sprintf-js": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.1.tgz",
- "integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw=",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
"dev": true
}
}
"integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
"dev": true
},
- "colors": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
- "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
- "dev": true
- },
"combined-stream": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
- "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+ "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
"dev": true,
"requires": {
"delayed-stream": "~1.0.0"
}
},
"commander": {
- "version": "2.16.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.16.0.tgz",
- "integrity": "sha512-sVXqklSaotK9at437sFlFpyOcJonxe0yST/AG9DkQKUdIE6IqGIMv4SfAQSKaJbSdVEJYItASCrBiVQHq1HQew==",
+ "version": "2.20.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
+ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
"dev": true
},
"commondir": {
"dev": true
},
"component-emitter": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
- "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
+ "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==",
"dev": true
},
"compressible": {
"dev": true
},
"convert-source-map": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
- "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=",
- "dev": true
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
+ "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
},
"cookie": {
"version": "0.4.0",
}
},
"cross-spawn": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
- "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
- "dev": true,
- "optional": true,
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
"requires": {
"lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
}
},
"css-selector-tokenizer": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
- "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
+ "version": "0.7.1",
+ "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.1.tgz",
+ "integrity": "sha512-xYL0AMZJ4gFzJQsHUKa5jiWWi2vH77WVNg7JYRyewwj6oPh4yb/y6Y9ZCw9dsj/9UauMhtuxR+ogQd//EdEVNA==",
"dev": true,
"requires": {
"cssesc": "^0.1.0",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"dev": true,
- "optional": true,
"requires": {
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
"dev": true
},
"electron-to-chromium": {
- "version": "1.3.52",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.52.tgz",
- "integrity": "sha1-0tnxJwuko7lnuDHEDvcftNmrXOA=",
+ "version": "1.3.124",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.124.tgz",
+ "integrity": "sha512-glecGr/kFdfeXUHOHAWvGcXrxNU+1wSO/t5B23tT1dtlvYB26GY8aHzZSWD7HqhqC800Lr+w/hQul6C5AF542w==",
"dev": true
},
"elliptic": {
}
},
"es6-promise": {
- "version": "4.2.5",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz",
- "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==",
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz",
+ "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==",
"dev": true
},
"es6-promisify": {
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
- },
- "dependencies": {
- "cross-spawn": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
- "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
- "requires": {
- "lru-cache": "^4.0.1",
- "shebang-command": "^1.2.0",
- "which": "^1.2.9"
- }
- }
}
},
"exit": {
"tmp": "^0.0.33"
},
"dependencies": {
- "tmp": {
- "version": "0.0.33",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
- "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
"dev": true,
"requires": {
- "os-tmpdir": "~1.0.2"
+ "safer-buffer": ">= 2.1.2 < 3"
}
}
}
}
},
"fast-deep-equal": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
- "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"dev": true
},
"fast-glob": {
"dev": true
},
"fastparse": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
- "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
+ "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
"dev": true
},
"faye-websocket": {
"integrity": "sha512-fFWz7LqRGMbyewY0Vxclw4712Cy+6Vd+1RAIJb7XY5qHpZi8BAA+Ue5sr4jAlDSI1+AD4b5WYl99NrGMtSaPzw=="
},
"form-data": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
- "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
"dev": true,
"requires": {
"asynckit": "^0.4.0",
- "combined-stream": "1.0.6",
+ "combined-stream": "^1.0.6",
"mime-types": "^2.1.12"
}
},
}
},
"fs-extra": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
- "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
+ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.2",
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1",
"wide-align": "^1.1.0"
+ },
+ "dependencies": {
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ }
}
},
"gaze": {
}
},
"graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
+ "version": "4.1.15",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
"dev": true
},
"growly": {
"dev": true
},
"har-validator": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
- "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
"dev": true,
"requires": {
- "ajv": "^5.1.0",
+ "ajv": "^6.5.5",
"har-schema": "^2.0.0"
- },
- "dependencies": {
- "ajv": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
- "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
- "dev": true,
- "requires": {
- "co": "^4.6.0",
- "fast-deep-equal": "^1.0.0",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.3.0"
- }
- }
}
},
"has": {
"chalk": "^2.4.1",
"commander": "^2.12.2",
"glob": "^7.1.2"
- },
- "dependencies": {
- "chalk": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
- "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- }
}
},
"htmlparser2": {
}
},
"iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "version": "0.4.23",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
"dev": true,
"requires": {
"safer-buffer": ">= 2.1.2 < 3"
},
"dependencies": {
"ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
},
"strip-ansi": {
"version": "5.2.0",
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
},
- "is-builtin-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
- "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
- "dev": true,
- "requires": {
- "builtin-modules": "^1.0.0"
- }
- },
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"dev": true
},
"is-glob": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
- "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
"dev": true,
"requires": {
"is-extglob": "^2.1.1"
"json-schema-traverse": "^0.3.0"
}
},
+ "fast-deep-equal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=",
+ "dev": true
+ },
+ "json-schema-traverse": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+ "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+ "dev": true
+ },
"schema-utils": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz",
"dev": true,
"requires": {
"colors": "1.1.2"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+ "dev": true
+ }
}
},
"jasminewd2": {
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"realpath-native": "^1.1.0"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"pretty-format": "^24.8.0"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"jsdom": "^11.5.1"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"jest-util": "^24.8.0"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"walker": "^1.0.7"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"throat": "^4.0.0"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"pretty-format": "^24.8.0"
}
},
- "jest-message-util": {
- "version": "24.0.0",
- "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-24.0.0.tgz",
- "integrity": "sha512-J9ROJIwz/IeC+eV1XSwnRK4oAwPuhmxEyYx1+K5UI+pIYwFZDSrfZaiWTdq0d2xYFw4Xiu+0KQWsdsQpgJMf3Q==",
- "dev": true,
- "requires": {
- "@babel/code-frame": "^7.0.0",
- "chalk": "^2.0.1",
- "micromatch": "^3.1.10",
- "slash": "^2.0.0",
- "stack-utils": "^1.0.1"
- },
- "dependencies": {
- "slash": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
- "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
- "dev": true
- }
- }
- },
"jest-mock": {
"version": "24.8.0",
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-24.8.0.tgz",
"throat": "^4.0.0"
},
"dependencies": {
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
- "graceful-fs": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
- "integrity": "sha512-jpSvDPV4Cq/bgtpndIWbI5hmYxhQGHPC4d4cqBPb4DLniCfhJokdXhwhaDuLBGLQdvvRum/UiX6ECVIPvDXqdg==",
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
"jest-message-util": {
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
"dev": true
},
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
"requires": {
"chalk": "^2.3.1",
"jest-util": "^24.0.0"
- },
- "dependencies": {
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- }
}
},
"jest-snapshot": {
}
},
"jest-util": {
- "version": "24.0.0",
- "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.0.0.tgz",
- "integrity": "sha512-QxsALc4wguYS7cfjdQSOr5HTkmjzkHgmZvIDkcmPfl1ib8PNV8QUWLwbKefCudWS0PRKioV+VbQ0oCUPC691fQ==",
+ "version": "24.7.1",
+ "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-24.7.1.tgz",
+ "integrity": "sha512-/KilOue2n2rZ5AnEBYoxOXkeTu6vi7cjgQ8MXEkih0oeAXT6JkS3fr7/j8+engCjciOU1Nq5loMSKe0A1oeX0A==",
"dev": true,
"requires": {
+ "@jest/console": "^24.7.1",
+ "@jest/fake-timers": "^24.7.1",
+ "@jest/source-map": "^24.3.0",
+ "@jest/test-result": "^24.7.1",
+ "@jest/types": "^24.7.0",
"callsites": "^3.0.0",
"chalk": "^2.0.1",
"graceful-fs": "^4.1.15",
"is-ci": "^2.0.0",
- "jest-message-util": "^24.0.0",
"mkdirp": "^0.5.1",
"slash": "^2.0.0",
"source-map": "^0.6.0"
},
"dependencies": {
- "graceful-fs": {
- "version": "4.1.15",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
- "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
"slash": {
"string-length": "^2.0.0"
},
"dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
"graceful-fs": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.0.tgz",
"requires": {
"merge-stream": "^1.0.1",
"supports-color": "^6.1.0"
- },
- "dependencies": {
- "supports-color": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
- "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- }
}
},
"jest-zone-patch": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
- "dev": true,
- "optional": true
+ "dev": true
},
"jsdom": {
"version": "11.12.0",
"dev": true
},
"json-schema-traverse": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
- "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"json-stringify-safe": {
"dev": true
},
"json5": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
- "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
- "dev": true
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
},
"jsonfile": {
"version": "4.0.0",
}
},
"jszip": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz",
- "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.2.1.tgz",
+ "integrity": "sha512-iCMBbo4eE5rb1VCpm5qXOAaUiRKRUKiItn8ah2YQQx9qymmSAY98eyQfioChEYcVQLh0zxJ3wS4A0mh90AVPvw==",
"dev": true,
"requires": {
- "core-js": "~2.3.0",
- "es6-promise": "~3.0.2",
- "lie": "~3.1.0",
+ "lie": "~3.3.0",
"pako": "~1.0.2",
- "readable-stream": "~2.0.6"
- },
- "dependencies": {
- "core-js": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz",
- "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=",
- "dev": true
- },
- "es6-promise": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz",
- "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=",
- "dev": true
- },
- "process-nextick-args": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
- "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
- "dev": true,
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.1",
- "isarray": "~1.0.0",
- "process-nextick-args": "~1.0.6",
- "string_decoder": "~0.10.x",
- "util-deprecate": "~1.0.1"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "dev": true
- }
+ "readable-stream": "~2.3.6",
+ "set-immediate-shim": "~1.0.1"
}
},
"karma-source-map-support": {
}
},
"lie": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
- "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+ "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
"dev": true,
"requires": {
"immediate": "~3.0.5"
"big.js": "^5.2.2",
"emojis-list": "^2.0.0",
"json5": "^1.0.1"
- },
- "dependencies": {
- "json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
- "dev": true,
- "requires": {
- "minimist": "^1.2.0"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
}
},
"locate-path": {
}
},
"lru-cache": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
- "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
"requires": {
"pseudomap": "^1.0.2",
"yallist": "^2.1.2"
"figgy-pudding": "^3.5.1"
}
},
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ },
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
"read-pkg-up": "^1.0.1",
"redent": "^1.0.0",
"trim-newlines": "^1.0.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true,
- "optional": true
- }
}
},
"merge-descriptors": {
"dev": true,
"requires": {
"source-map": "^0.5.6"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
}
},
"merge-stream": {
"dev": true
},
"mime-db": {
- "version": "1.35.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz",
- "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==",
+ "version": "1.38.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz",
+ "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==",
"dev": true
},
"mime-types": {
- "version": "2.1.19",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz",
- "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==",
+ "version": "2.1.22",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz",
+ "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==",
"dev": true,
"requires": {
- "mime-db": "~1.35.0"
+ "mime-db": "~1.38.0"
}
},
"mimic-fn": {
}
},
"minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
"minipass": {
"dev": true,
"requires": {
"minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ }
}
},
"moment": {
"dev": true
},
"nan": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
- "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
+ "version": "2.13.2",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
+ "integrity": "sha512-TghvYc72wlMGMVMluVo9WRJc0mB8KxxF/gZ4YYFy7V2ZQX9l7rgbPg7vjS9mt6U5HXODVFVI2bOduCzwOMv/lw==",
"dev": true,
"optional": true
},
"integrity": "sha512-COGMatd+YrwJb3LSobagDC+t2PlSh4GkgG75Akh9QbXOSdFFPkbGmZvILg2xO4Hc+xicacvHp+6GINvjIeJwkA=="
},
"ngx-bootstrap": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ngx-bootstrap/-/ngx-bootstrap-3.2.0.tgz",
- "integrity": "sha512-oLSLIWZgRiIfcuxyXLMZUOhX3wZtg6lpuMbdo/0UzMDg2bSOe1XPskcKZ/iuOa3FOlU9rjuYMzswHYYV5f/QCA=="
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ngx-bootstrap/-/ngx-bootstrap-4.3.0.tgz",
+ "integrity": "sha512-ZPS6V2yLEeqB/7KIlVohS8qUdtFa1bgUB/sSPWRcXqOWU3EKhORetZoXG6m2F5ILYDe5hwQvBEjdHPlEz2piOg=="
},
"nice-try": {
"version": "1.0.5",
"dev": true,
"optional": true
},
- "aws4": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
- "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
- "dev": true,
- "optional": true
- },
"chalk": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
"supports-color": "^2.0.0"
}
},
- "har-validator": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
- "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "cross-spawn": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+ "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
"dev": true,
"optional": true,
"requires": {
- "ajv": "^6.5.5",
- "har-schema": "^2.0.0"
+ "lru-cache": "^4.0.1",
+ "which": "^1.2.9"
}
},
"nan": {
"punycode": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
- "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
- "dev": true,
- "optional": true
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
},
"request": {
"version": "2.88.0",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true,
"optional": true
- },
- "tough-cookie": {
- "version": "2.4.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
- "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
- "dev": true,
- "optional": true,
- "requires": {
- "psl": "^1.1.24",
- "punycode": "^1.4.1"
- }
}
}
},
}
},
"normalize-package-data": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
- "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
"dev": true,
"requires": {
"hosted-git-info": "^2.1.4",
- "is-builtin-module": "^1.0.0",
+ "resolve": "^1.10.0",
"semver": "2 || 3 || 4 || 5",
"validate-npm-package-license": "^3.0.1"
}
"dev": true
},
"oauth-sign": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
- "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
"dev": true
},
"object-assign": {
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
"dev": true
},
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
- },
"ansi-styles": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"through": "^2.3.6"
}
},
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"opn": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
"pinkie-promise": "^2.0.0"
}
},
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
- }
- },
"supports-color": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
"dev": true
- },
- "tmp": {
- "version": "0.0.33",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
- "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
- "dev": true,
- "requires": {
- "os-tmpdir": "~1.0.2"
- }
}
}
},
"wordwrap": "~0.0.2"
},
"dependencies": {
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "minimist": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
"dev": true
}
}
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"wordwrap": "~1.0.0"
+ },
+ "dependencies": {
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ }
}
},
"original": {
"dev": true
},
"os-locale": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
- "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
- "dev": true,
- "optional": true,
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
"requires": {
- "lcid": "^1.0.0"
+ "execa": "^0.7.0",
+ "lcid": "^1.0.0",
+ "mem": "^1.1.0"
}
},
"os-name": {
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
},
"p-is-promise": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz",
- "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
+ "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
"dev": true
},
"p-limit": {
"yallist": "^3.0.3"
}
},
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ },
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
}
},
"pako": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
- "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz",
+ "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==",
"dev": true
},
"parallel-transform": {
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A="
},
"path-parse": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
- "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
"dev": true
},
"path-to-regexp": {
"iconv-lite": "^0.4.24",
"linebreak": "^0.3.0",
"pdfkit": "^0.10.0"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ }
}
},
"performance-now": {
"supports-color": "^6.1.0"
},
"dependencies": {
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "dependencies": {
- "supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- }
- }
- },
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
- },
- "supports-color": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
- "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
}
}
},
"arrify": "^1.0.1",
"minimatch": "^3.0.4"
}
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
}
}
},
"pinkie-promise": "^2.0.0"
}
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
},
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
"source-map-support": {
"version": "0.4.18",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
"uuid": "^3.1.0"
},
"dependencies": {
- "fs-extra": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz",
- "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==",
- "dev": true,
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- },
"q": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
"integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==",
- "dev": true,
- "optional": true
+ "dev": true
},
"public-encrypt": {
"version": "4.0.3",
}
},
"punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
- "dev": true
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
},
"q": {
"version": "1.4.1",
"buffer-equal": "0.0.1",
"minimist": "^1.1.3",
"through2": "^2.0.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
}
},
"randombytes": {
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
"dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
}
}
},
"dev": true
},
"repeat-element": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz",
- "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
"dev": true
},
"repeat-string": {
"dev": true
},
"camelcase": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz",
- "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
"dev": true
},
- "chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- }
- },
"cliui": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
"dev": true
},
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
"lcid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
}
},
"mem": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz",
- "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
+ "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
"dev": true,
"requires": {
"map-age-cleaner": "^0.1.1",
- "mimic-fn": "^1.0.0",
+ "mimic-fn": "^2.0.0",
"p-is-promise": "^2.0.0"
}
},
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true
+ },
"os-locale": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
}
},
"p-limit": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz",
- "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+ "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
}
},
"p-try": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz",
- "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
"dev": true
},
"pump": {
"once": "^1.3.1"
}
},
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
- "requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- }
- },
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"ansi-regex": "^3.0.0"
}
},
- "which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
- "dev": true
- },
"yargs": {
"version": "12.0.5",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
}
},
"request": {
- "version": "2.87.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
- "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
- "aws4": "^1.6.0",
+ "aws4": "^1.8.0",
"caseless": "~0.12.0",
- "combined-stream": "~1.0.5",
- "extend": "~3.0.1",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
"forever-agent": "~0.6.1",
- "form-data": "~2.3.1",
- "har-validator": "~5.0.3",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
- "mime-types": "~2.1.17",
- "oauth-sign": "~0.8.2",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
"performance-now": "^2.1.0",
- "qs": "~6.5.1",
- "safe-buffer": "^5.1.1",
- "tough-cookie": "~2.3.3",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
"tunnel-agent": "^0.6.0",
- "uuid": "^3.1.0"
+ "uuid": "^3.3.2"
}
},
"request-promise-core": {
"dev": true
},
"resolve": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
- "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
+ "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
"dev": true,
"requires": {
- "path-parse": "^1.0.5"
+ "path-parse": "^1.0.6"
}
},
"resolve-cwd": {
"dev": true
},
"rimraf": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
"dev": true,
"requires": {
- "glob": "^7.0.5"
+ "glob": "^7.1.3"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
}
},
"ripemd160": {
"pump": "^3.0.0"
}
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"rimraf": "^2.5.4",
"tmp": "0.0.30",
"xml2js": "^0.4.17"
+ },
+ "dependencies": {
+ "tmp": {
+ "version": "0.0.30",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
+ "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.1"
+ }
+ }
}
},
"selfsigned": {
}
},
"semver": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
- "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+ "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
"dev": true
},
"semver-dsl": {
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
},
+ "set-immediate-shim": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz",
+ "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
+ "dev": true
+ },
"set-value": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
"requires": {
"is-extendable": "^0.1.0"
}
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
}
}
},
"dev": true
},
"source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "version": "0.7.3",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
+ "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"dev": true
},
"source-map-loader": {
}
},
"source-map-support": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz",
- "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==",
+ "version": "0.5.10",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz",
+ "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==",
"dev": true,
"requires": {
"buffer-from": "^1.0.0",
"dev": true
},
"spdx-correct": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
- "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
"dev": true,
"requires": {
"spdx-expression-parse": "^3.0.0",
}
},
"spdx-exceptions": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
- "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==",
"dev": true
},
"spdx-expression-parse": {
}
},
"spdx-license-ids": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz",
- "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz",
+ "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==",
"dev": true
},
"spdy": {
"dev": true
},
"sshpk": {
- "version": "1.14.2",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
- "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
"dev": true,
"requires": {
"asn1": "~0.2.3",
}
},
"stack-utils": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz",
- "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz",
+ "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==",
"dev": true
},
"static-eval": {
}
},
"string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"requires": {
- "code-point-at": "^1.0.0",
- "is-fullwidth-code-point": "^1.0.0",
- "strip-ansi": "^3.0.0"
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
}
},
"string_decoder": {
}
},
"supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
"dev": true,
"requires": {
"has-flag": "^3.0.0"
"figgy-pudding": "^3.5.1"
}
},
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ },
"yallist": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz",
"dev": true
},
"tmp": {
- "version": "0.0.30",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
- "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"requires": {
- "os-tmpdir": "~1.0.1"
+ "os-tmpdir": "~1.0.2"
}
},
"tmpl": {
"dev": true
},
"tough-cookie": {
- "version": "2.3.4",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
- "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
"dev": true,
"requires": {
+ "psl": "^1.1.24",
"punycode": "^1.4.1"
},
"dependencies": {
"dev": true,
"requires": {
"punycode": "^2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ }
}
},
"traverse": {
"fs-extra": "6.0.1",
"json5": "^0.5.0",
"lodash": "^4.17.10"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
+ "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "json5": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
+ "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "dev": true
+ }
}
},
"ts-node": {
"path-type": "^3.0.0"
}
},
+ "fs-extra": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
+ "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
"globby": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
}
}
},
"version": "0.14.5",
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
- "dev": true,
- "optional": true
+ "dev": true
},
"type-check": {
"version": "0.3.2",
}
},
"upath": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
- "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz",
+ "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==",
"dev": true
},
"uri-js": {
"dev": true,
"requires": {
"punycode": "^2.1.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "dev": true
+ }
}
},
"urix": {
"requires": {
"punycode": "1.3.2",
"querystring": "0.2.0"
- },
- "dependencies": {
- "punycode": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
- "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
- }
}
},
"url-parse": {
"dev": true
},
"validate-npm-package-license": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
- "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
"dev": true,
"requires": {
"spdx-correct": "^3.0.0",
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
"dev": true
},
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
- "dev": true
- },
"lcid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"dev": true,
"requires": {
- "is-fullwidth-code-point": "^2.0.0",
- "strip-ansi": "^4.0.0"
- },
- "dependencies": {
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "dev": true,
- "requires": {
- "ansi-regex": "^3.0.0"
- }
- }
+ "has-flag": "^3.0.0"
}
},
"webpack-dev-middleware": {
"webpack-log": "^2.0.0"
}
},
- "which-module": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
- "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
- "dev": true
- },
"yargs": {
"version": "12.0.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.2.tgz",
"dev": true,
"requires": {
"iconv-lite": "0.4.24"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ }
}
},
"whatwg-mimetype": {
}
},
"which-module": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
- "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
- "dev": true,
- "optional": true
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
},
"wide-align": {
"version": "1.1.3",
}
},
"wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
"dev": true
},
"worker-farm": {
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
+ },
+ "dependencies": {
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ }
}
},
"wrappy": {
"dev": true
},
"y18n": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
- "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
- "dev": true
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
},
"yallist": {
"version": "2.1.2",
"dev": true,
"optional": true
},
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "lcid": "^1.0.0"
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+ "dev": true,
+ "optional": true
+ },
"y18n": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
"integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
"dev": true,
"optional": true
+ },
+ "yargs-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+ "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "camelcase": "^3.0.0"
+ }
}
}
},
"yargs-parser": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
- "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
- "dev": true,
- "optional": true,
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz",
+ "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==",
"requires": {
- "camelcase": "^3.0.0"
+ "camelcase": "^4.1.0"
},
"dependencies": {
"camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
- "dev": true,
- "optional": true
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0="
}
}
},
"yn": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz",
- "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.0.tgz",
+ "integrity": "sha512-kKfnnYkbTfrAdd0xICNFw7Atm8nKpLcLv9AZGEt+kczL/WQVai4e2V6ZN8U/O+iI6WrNuJjNNOyu4zfhl9D3Hg==",
"dev": true
},
"zone.js": {
"@auth0/angular-jwt": "2.1.0",
"@ngx-translate/i18n-polyfill": "1.0.0",
"@swimlane/ngx-datatable": "14.0.0",
- "awesome-bootstrap-checkbox": "0.3.7",
- "bootstrap": "3.4.1",
+ "awesome-bootstrap-checkbox": "1.0.1",
+ "bootstrap": "4.3.1",
"chart.js": "2.7.3",
"core-js": "2.6.5",
"detect-browser": "4.1.0",
"ng2-charts": "1.6.0",
"ng2-toastr": "zzakir/ng2-toastr#0eafd72",
"ng2-tree": "2.0.0-rc.11",
- "ngx-bootstrap": "3.2.0",
+ "ngx-bootstrap": "4.3.0",
"rxjs": "6.4.0",
"rxjs-compat": "6.4.0",
"tslib": "1.9.3",
-@import '../defaults';
+@import 'defaults';
.dashboard {
background-color: $color-whitesmoke-gray;
margin-top: 2.5vw;
}
- @media (max-width: $screen-sm-max) {
+ @media (max-width: $screen-md-max) {
margin-top: 9vw;
}
<tab heading="Overview"
i18n-heading
[active]="url === '/block/iscsi/overview'"
- (select)="navigateTo('/block/iscsi/overview')">
+ (selectTab)="navigateTo('/block/iscsi/overview')">
</tab>
<tab heading="Targets"
i18n-heading
[active]="url === '/block/iscsi/targets'"
- (select)="navigateTo('/block/iscsi/targets')">
+ (selectTab)="navigateTo('/block/iscsi/targets')">
</tab>
</tabset>
-<div class="col-sm-6 col-lg-6">
- <legend i18n>iSCSI Topology</legend>
- <tree [tree]="tree"
- (nodeSelected)="onNodeSelected($event)">
- <ng-template let-node>
- <span class="node-name"
- [innerHTML]="node.value"></span>
- <span> </span>
+<div class="row">
+ <div class="col-6">
+ <legend i18n>iSCSI Topology</legend>
+ <tree [tree]="tree"
+ (nodeSelected)="onNodeSelected($event)">
+ <ng-template let-node>
+ <span class="node-name"
+ [innerHTML]="node.value"></span>
+ <span> </span>
- <span class="label"
- [ngClass]="{'label-success': ['logged_in'].includes(node.status), 'label-danger': ['logged_out'].includes(node.status)}">
- {{ node.status }}
- </span>
- </ng-template>
- </tree>
-</div>
+ <span class="badge"
+ [ngClass]="{'badge-success': ['logged_in'].includes(node.status), 'badge-danger': ['logged_out'].includes(node.status)}">
+ {{ node.status }}
+ </span>
+ </ng-template>
+ </tree>
+ </div>
-<div class="col-sm-6 col-lg-6 metadata"
- *ngIf="data">
- <legend>{{ title }}</legend>
+ <div class="col-6 metadata"
+ *ngIf="data">
+ <legend>{{ title }}</legend>
- <cd-table #detailTable
- [data]="data"
- columnMode="flex"
- [columns]="columns"
- [limit]="0">
- </cd-table>
+ <cd-table #detailTable
+ [data]="data"
+ columnMode="flex"
+ [columns]="columns"
+ [limit]="0">
+ </cd-table>
+ </div>
</div>
<ng-template #highlightTpl
children: [{ id: 'disk_rbd_disk_1', value: 'rbd/disk_1' }],
settings: {
cssClasses: {
- expanded: _.join([Icons.width, Icons.large, Icons.disk], ' '),
- leaf: _.join([Icons.width, Icons.disk], ' ')
+ expanded: _.join([Icons.large, Icons.disk], ' '),
+ leaf: _.join([Icons.disk], ' ')
},
selectionAllowed: false
},
children: [{ value: 'node1:192.168.100.201' }],
settings: {
cssClasses: {
- expanded: _.join([Icons.width, Icons.large, Icons.server], ' '),
- leaf: _.join([Icons.width, Icons.large, Icons.server], ' ')
+ expanded: _.join([Icons.large, Icons.server], ' '),
+ leaf: _.join([Icons.large, Icons.server], ' ')
},
selectionAllowed: false
},
id: 'disk_rbd_disk_1',
settings: {
cssClasses: {
- expanded: _.join([Icons.width, Icons.large, Icons.disk], ' '),
- leaf: _.join([Icons.width, Icons.disk], ' ')
+ expanded: _.join([Icons.large, Icons.disk], ' '),
+ leaf: _.join([Icons.disk], ' ')
}
},
value: 'rbd/disk_1'
],
settings: {
cssClasses: {
- expanded: _.join([Icons.width, Icons.large, Icons.user], ' '),
- leaf: _.join([Icons.width, Icons.user], ' ')
+ expanded: _.join([Icons.large, Icons.user], ' '),
+ leaf: _.join([Icons.user], ' ')
},
selectionAllowed: false
},
children: [],
settings: {
cssClasses: {
- expanded: _.join([Icons.width, Icons.large, Icons.user], ' '),
- leaf: _.join([Icons.width, Icons.user], ' ')
+ expanded: _.join([Icons.large, Icons.user], ' '),
+ leaf: _.join([Icons.user], ' ')
},
selectionAllowed: false
},
],
id: 'root',
settings: {
- cssClasses: { expanded: _.join([Icons.width, Icons.large, Icons.bullseye], ' ') },
+ cssClasses: { expanded: _.join([Icons.large, Icons.bullseye], ' ') },
static: true
},
value: 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw'
this.metadata = { root: this.selectedItem.target_controls };
const cssClasses = {
target: {
- expanded: _.join([Icons.width, Icons.large, Icons.bullseye], ' ')
+ expanded: _.join([Icons.large, Icons.bullseye], ' ')
},
initiators: {
- expanded: _.join([Icons.width, Icons.large, Icons.user], ' '),
- leaf: _.join([Icons.width, Icons.user], ' ')
+ expanded: _.join([Icons.large, Icons.user], ' '),
+ leaf: _.join([Icons.user], ' ')
},
groups: {
- expanded: _.join([Icons.width, Icons.large, Icons.user], ' '),
- leaf: _.join([Icons.width, Icons.user], ' ')
+ expanded: _.join([Icons.large, Icons.user], ' '),
+ leaf: _.join([Icons.user], ' ')
},
disks: {
- expanded: _.join([Icons.width, Icons.large, Icons.disk], ' '),
- leaf: _.join([Icons.width, Icons.disk], ' ')
+ expanded: _.join([Icons.large, Icons.disk], ' '),
+ leaf: _.join([Icons.disk], ' ')
},
portals: {
- expanded: _.join([Icons.width, Icons.large, Icons.server], ' '),
- leaf: _.join([Icons.width, Icons.large, Icons.server], ' ')
+ expanded: _.join([Icons.large, Icons.server], ' '),
+ leaf: _.join([Icons.large, Icons.server], ' ')
}
};
<ng-container class="modal-content">
<form name="discoveryForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="discoveryForm"
novalidate>
<div class="modal-body">
<!-- User -->
- <div class="form-group"
- [ngClass]="{'has-error': discoveryForm.showError('user', formDir)}">
- <label class="control-label col-sm-4"
+ <div class="form-group row"
+ [ngClass]="{':invalid': discoveryForm.showError('user', formDir)}">
+ <label class="col-form-label col-sm-4"
for="user"
i18n>User</label>
<div class="col-sm-8">
class="form-control"
formControlName="user"
type="text">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="discoveryForm.showError('user', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="discoveryForm.showError('user', formDir, 'pattern')"
i18n>Usernames must have a length of 8 to 64 characters and
can only contain letters, '.', '@', '-', '_' or ':'.</span>
</div>
<!-- Password -->
- <div class="form-group"
- [ngClass]="{'has-error': discoveryForm.showError('password', formDir)}">
- <label class="control-label col-sm-4"
+ <div class="form-group row"
+ [ngClass]="{':invalid': discoveryForm.showError('password', formDir)}">
+ <label class="col-form-label col-sm-4"
for="password"
i18n>Password</label>
<div class="col-sm-8">
formControlName="password"
type="password">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="password">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdCopy2ClipboardButton="password">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="discoveryForm.showError('password', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="discoveryForm.showError('password', formDir, 'pattern')"
i18n>Passwords must have a length of 12 to 16 characters
and can only contain letters, '@', '-', '_' or '/'.</span>
</div>
<!-- mutual_user -->
- <div class="form-group"
- [ngClass]="{'has-error': discoveryForm.showError('mutual_user', formDir)}">
- <label class="control-label col-sm-4"
+ <div class="form-group row"
+ [ngClass]="{':invalid': discoveryForm.showError('mutual_user', formDir)}">
+ <label class="col-form-label col-sm-4"
for="mutual_user">
<ng-container i18n>Mutual User</ng-container>
</label>
formControlName="mutual_user"
type="text">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="discoveryForm.showError('mutual_user', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="discoveryForm.showError('mutual_user', formDir, 'pattern')"
i18n>Usernames must have a length of 8 to 64 characters and
can only contain letters, '.', '@', '-', '_' or ':'.</span>
</div>
<!-- mutual_password -->
- <div class="form-group"
- [ngClass]="{'has-error': discoveryForm.showError('mutual_password', formDir)}">
- <label class="control-label col-sm-4"
+ <div class="form-group row"
+ [ngClass]="{':invalid': discoveryForm.showError('mutual_password', formDir)}">
+ <label class="col-form-label col-sm-4"
for="mutual_password"
i18n>Mutual Password</label>
<div class="col-sm-8">
formControlName="mutual_password"
type="password">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="mutual_password">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdCopy2ClipboardButton="mutual_password">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="discoveryForm.showError('mutual_password', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="discoveryForm.showError('mutual_password', formDir, 'pattern')"
i18n>Passwords must have a length of 12 to 16 characters and
can only contain letters, '@', '-', '_' or '/'.</span>
<div class="col-sm-12 col-lg-6">
<form name="targetForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="targetForm"
novalidate
*ngIf="targetForm">
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 i18n="form title|Example: Create Pool@@formTitle"
- class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3>
- </div>
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
- <div class="panel-body">
+ <div class="card-body">
<!-- Target IQN -->
- <div class="form-group"
- [ngClass]="{'has-error': targetForm.showError('target_iqn', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': targetForm.showError('target_iqn', formDir)}">
+ <label class="col-form-label col-sm-3"
for="target_iqn">
<ng-container i18n>Target IQN</ng-container>
<span class="required"></span>
id="target_iqn"
name="target_iqn"
formControlName="target_iqn" />
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
id="ecp-info-button"
type="button"
(click)="targetSettingsModal()">
- <i [ngClass]="[icons.deepCheck, icons.width]"
+ <i [ngClass]="[icons.deepCheck]"
aria-hidden="true"></i>
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="targetForm.showError('target_iqn', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="targetForm.showError('target_iqn', formDir, 'pattern')"
i18n>IQN has wrong pattern.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="targetForm.showError('target_iqn', formDir, 'iqn')">
- <ng-container i18n>An IQN has the following notation 'iqn.$year-$month.$reversedAddress:$definedName'</ng-container>
+ <ng-container i18n>An IQN has the following notation
+ 'iqn.$year-$month.$reversedAddress:$definedName'</ng-container>
<br>
<ng-container i18n>For example: iqn.2016-06.org.dashboard:storage:disk.sn-a8675309</ng-container>
<br>
i18n>More information</a>
</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="hasAdvancedSettings(targetForm.getValue('target_controls'))"
i18n>This target has modified advanced settings.</span>
<hr />
</div>
<!-- Portals -->
- <div class="form-group"
- [ngClass]="{'has-error': targetForm.showError('portals', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': targetForm.showError('portals', formDir)}">
+ <label class="col-form-label col-sm-3"
for="portals">
<ng-container i18n>Portals</ng-container>
<span class="required"></span>
<ng-container *ngFor="let portal of portals.value; let i = index">
<div class="input-group cd-mb">
- <input class="form-control"
+ <input class="cd-form-control"
type="text"
[value]="portal"
disabled />
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
type="button"
(click)="removePortal(i, portal)">
- <i [ngClass]="[icons.destroy, icons.width]"
+ <i [ngClass]="[icons.destroy]"
aria-hidden="true"></i>
</button>
</span>
</div>
</ng-container>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="targetForm.showError('portals', formDir, 'minGateways')"
i18n>At least {{ minimum_gateways }} gateways are required.</span>
[options]="portalsSelections"
[messages]="messages.portals"
(selection)="onPortalSelection($event)"
- elemClass="btn btn-default pull-right">
- <i [ngClass]="[icons.add, icons.width]"></i>
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add portal</ng-container>
</cd-select>
</div>
</div>
<!-- Images -->
- <div class="form-group"
- [ngClass]="{'has-error': targetForm.showError('disks', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': targetForm.showError('disks', formDir)}">
+ <label class="col-form-label col-sm-3"
for="disks"
i18n>Images</label>
<div class="col-sm-9">
<ng-container *ngFor="let image of targetForm.getValue('disks'); let i = index">
<div class="input-group cd-mb">
- <input class="form-control"
+ <input class="cd-form-control"
type="text"
[value]="image"
disabled />
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
type="button"
(click)="imageSettingsModal(image)">
- <i [ngClass]="[icons.deepCheck, icons.width]"
+ <i [ngClass]="[icons.deepCheck]"
aria-hidden="true"></i>
</button>
- <button class="btn btn-default"
+ <button class="btn btn-light"
type="button"
(click)="removeImage(i, image)">
- <i [ngClass]="[icons.destroy, icons.width]"
+ <i [ngClass]="[icons.destroy]"
aria-hidden="true"></i>
</button>
</span>
</div>
- <span class="help-block">
+ <span class="form-text text-muted">
<ng-container *ngIf="backstores.length > 1"
i18n>Backstore: {{ imagesSettings[image].backstore | iscsiBackstore }}. </ng-container>
</span>
</ng-container>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="targetForm.showError('disks', formDir, 'required')"
i18n>At least 1 image is required.</span>
[options]="imagesSelections"
[messages]="messages.images"
(selection)="onImageSelection($event)"
- elemClass="btn btn-default pull-right">
- <i [ngClass]="[icons.add, icons.width]"></i>
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add image</ng-container>
</cd-select>
</div>
</div>
<!-- acl_enabled -->
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
<div class="checkbox checkbox-primary">
<input type="checkbox"
formControlName="acl_enabled"
</div>
<!-- Initiators -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="targetForm.getValue('acl_enabled')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="initiators"
i18n>Initiators</label>
<div class="col-sm-9"
formArrayName="initiators">
- <div class="panel panel-default"
+ <div class="card mb-2"
*ngFor="let initiator of initiators.controls; let ii = index"
[formGroupName]="ii">
- <div class="panel-heading">
+ <div class="card-header">
<ng-container i18n>Initiator</ng-container>: {{ initiator.getValue('client_iqn') }}
<button type="button"
class="close"
(click)="removeInitiator(ii)">
- <i [ngClass]="[icons.deepCheck, icons.width]"></i>
+ <i [ngClass]="[icons.deepCheck]"></i>
</button>
</div>
- <div class="panel-body">
+ <div class="card-body">
<!-- Initiator: Name -->
- <div class="form-group"
- [ngClass]="{'has-error': initiator.showError('client_iqn', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': initiator.showError('client_iqn', formDir)}">
+ <label class="col-form-label col-sm-3"
for="client_iqn">
<ng-container i18n>Client IQN</ng-container>
<span class="required"></span>
formControlName="client_iqn"
(blur)="updatedInitiatorSelector()">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('client_iqn', formDir, 'notUnique')"
i18n>Initiator IQN needs to be unique.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('client_iqn', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('client_iqn', formDir, 'pattern')"
i18n>IQN has wrong pattern.</span>
</div>
<ng-container formGroupName="auth">
<!-- Initiator: User -->
- <div class="form-group"
- [ngClass]="{'has-error': initiator.showError('user', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': initiator.showError('user', formDir)}">
+ <label class="col-form-label col-sm-3"
for="user"
i18n>User</label>
<div class="col-sm-9">
class="form-control"
formControlName="user"
type="text">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('user', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('user', formDir, 'pattern')"
i18n>Usernames must have a length of 8 to 64 characters and
can only contain letters, '.', '@', '-', '_' or ':'.</span>
</div>
<!-- Initiator: Password -->
- <div class="form-group"
- [ngClass]="{'has-error': initiator.showError('password', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': initiator.showError('password', formDir)}">
+ <label class="col-form-label col-sm-3"
for="password"
i18n>Password</label>
<div class="col-sm-9">
formControlName="password"
type="password">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
[cdPasswordButton]="'password' + ii">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
[cdCopy2ClipboardButton]="'password' + ii">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('password', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('password', formDir, 'pattern')"
i18n>Passwords must have a length of 12 to 16 characters
and can only contain letters, '@', '-', '_' or '/'.</span>
<!-- Initiator: mutual_user -->
- <div class="form-group"
- [ngClass]="{'has-error': initiator.showError('mutual_user', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': initiator.showError('mutual_user', formDir)}">
+ <label class="col-form-label col-sm-3"
for="mutual_user">
<ng-container i18n>Mutual User</ng-container>
</label>
formControlName="mutual_user"
type="text">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('mutual_user', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('mutual_user', formDir, 'pattern')"
i18n>Usernames must have a length of 8 to 64 characters and
can only contain letters, '.', '@', '-', '_' or ':'.</span>
</div>
<!-- Initiator: mutual_password -->
- <div class="form-group"
- [ngClass]="{'has-error': initiator.showError('mutual_password', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': initiator.showError('mutual_password', formDir)}">
+ <label class="col-form-label col-sm-3"
for="mutual_password"
i18n>Mutual Password</label>
<div class="col-sm-9">
formControlName="mutual_password"
type="password">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
[cdPasswordButton]="'mutual_password' + ii">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
[cdCopy2ClipboardButton]="'mutual_password' + ii">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('mutual_password', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="initiator.showError('mutual_password', formDir, 'pattern')"
i18n>Passwords must have a length of 12 to 16 characters and
can only contain letters, '@', '-', '_' or '/'.</span>
</ng-container>
<!-- Initiator: Images -->
- <div class="form-group"
- [ngClass]="{'has-error': initiator.showError('luns', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': initiator.showError('luns', formDir)}">
+ <label class="col-form-label col-sm-3"
for="luns"
i18n>Images</label>
<div class="col-sm-9">
<ng-container *ngFor="let image of initiator.getValue('luns'); let li = index">
<div class="input-group cd-mb">
- <input class="form-control"
+ <input class="cd-form-control"
type="text"
[value]="image"
disabled />
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
type="button"
(click)="removeInitiatorImage(initiator, li, ii, image)">
- <i [ngClass]="[icons.destroy, icons.width]"
+ <i [ngClass]="[icons.destroy]"
aria-hidden="true"></i>
</button>
</span>
<cd-select [data]="initiator.getValue('luns')"
[options]="imagesInitiatorSelections[ii]"
[messages]="messages.initiatorImage"
- elemClass="btn btn-default pull-right">
- <i [ngClass]="[icons.add, icons.width]"></i>
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add image</ng-container>
</cd-select>
</div>
<div class="row">
<div class="col-md-12">
- <span class="text-muted"
+ <span class="form-text text-muted"
*ngIf="initiators.controls.length === 0"
i18n>No items added.</span>
<button (click)="addInitiator(); false"
- class="btn btn-default pull-right">
- <i [ngClass]="[icons.add, icons.width]"></i>
+ class="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add initiator</ng-container>
</button>
</div>
</div>
<!-- Groups -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="targetForm.getValue('acl_enabled')"
- [ngClass]="{'has-error': targetForm.showError('groups', formDir)}">
- <label class="control-label col-sm-3"
+ [ngClass]="{':invalid': targetForm.showError('groups', formDir)}">
+ <label class="col-form-label col-sm-3"
for="initiators"
i18n>Groups</label>
<div class="col-sm-9"
formArrayName="groups">
- <div class="panel panel-default"
+ <div class="card mb-2"
*ngFor="let group of groups.controls; let gi = index"
[formGroupName]="gi">
- <div class="panel-heading">
+ <div class="card-header">
<ng-container i18n>Group</ng-container>: {{ group.getValue('group_id') }}
<button type="button"
class="close"
(click)="groups.removeAt(gi)">
- <i [ngClass]="[icons.destroy, icons.width]"></i>
+ <i [ngClass]="[icons.destroy]"></i>
</button>
</div>
- <div class="panel-body">
+ <div class="card-body">
<!-- Group: group_id -->
- <div class="form-group">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="group_id">
<ng-container i18n>Name</ng-container>
<span class="required"></span>
</div>
<!-- Group: members -->
- <div class="form-group"
- [ngClass]="{'has-error': group.showError('members', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': group.showError('members', formDir)}">
+ <label class="col-form-label col-sm-3"
for="members">
<ng-container i18n>Initiators</ng-container>
</label>
<div class="col-sm-9">
<ng-container *ngFor="let member of group.getValue('members'); let i = index">
<div class="input-group cd-mb">
- <input class="form-control"
+ <input class="cd-form-control"
type="text"
[value]="member"
disabled />
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
type="button"
(click)="removeGroupInitiator(group, i, gi)">
- <i [ngClass]="[icons.destroy, icons.width]"
+ <i [ngClass]="[icons.destroy]"
aria-hidden="true"></i>
</button>
</span>
[options]="groupMembersSelections[gi]"
[messages]="messages.groupInitiator"
(selection)="onGroupMemberSelection($event)"
- elemClass="btn btn-default pull-right">
- <i [ngClass]="[icons.add, icons.width]"></i>
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add initiator</ng-container>
</cd-select>
</div>
</div>
<!-- Group: disks -->
- <div class="form-group"
- [ngClass]="{'has-error': group.showError('disks', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': group.showError('disks', formDir)}">
+ <label class="col-form-label col-sm-3"
for="disks">
<ng-container i18n>Images</ng-container>
</label>
<div class="col-sm-9">
<ng-container *ngFor="let disk of group.getValue('disks'); let i = index">
<div class="input-group cd-mb">
- <input class="form-control"
+ <input class="cd-form-control"
type="text"
[value]="disk"
disabled />
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
type="button"
(click)="removeGroupDisk(group, i, gi)">
- <i [ngClass]="[icons.destroy, icons.width]"
+ <i [ngClass]="[icons.destroy]"
aria-hidden="true"></i>
</button>
</span>
<cd-select [data]="group.getValue('disks')"
[options]="groupDiskSelections[gi]"
[messages]="messages.initiatorImage"
- elemClass="btn btn-default pull-right">
- <i [ngClass]="[icons.add, icons.width]"></i>
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add image</ng-container>
</cd-select>
</div>
<div class="row">
<div class="col-md-12">
- <span class="text-muted"
+ <span class="form-text text-muted"
*ngIf="groups.controls.length === 0"
i18n>No items added.</span>
<button (click)="addGroup(); false"
- class="btn btn-default pull-right">
- <i [ngClass]="[icons.add, icons.width]"></i>
+ class="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add group</ng-container>
</button>
</div>
</div>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
- <cd-submit-button
- [form]="formDir"
- (submitAction)="submit()"
- i18n="form action button|Example: Create Pool@@formActionButton"
- type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="submit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="formDir">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
<!-- BACKSTORE -->
<div class="form-group row">
<div class="col-sm-12">
- <label class="control-label"
+ <label class="col-form-label"
i18n>Backstore</label>
<select id="backstore"
name="backstore"
<div class="form-group row"
*ngFor="let setting of disk_default_controls[bs] | keyvalue">
<div class="col-sm-12">
- <label class="control-label"
+ <label class="col-form-label"
for="{{ setting.key }}">{{ setting.key }}</label>
<input type="number"
class="form-control"
[(ngModel)]="model[bs][setting.key]">
- <span class="help-block">{{ helpText[setting.key]?.help }}</span>
+ <span class="form-text text-muted">{{ helpText[setting.key]?.help }}</span>
</div>
</div>
</ng-container>
<div class="modal-footer">
<div class="button-group text-right">
- <button class="btn btn-sm btn-primary"
+ <button class="btn btn-secondary"
(click)="save()"
i18n>Confirm</button>
<cd-back-button [back]="modalRef.hide"
<ng-container class="modal-content">
<form name="settingsForm"
- class="form"
#formDir="ngForm"
[formGroup]="settingsForm"
novalidate>
<div class="form-group row"
*ngFor="let setting of settingsForm.controls | keyvalue"
- [ngClass]="{'has-error': settingsForm.showError(setting.key, formDir)}">
+ [ngClass]="{':invalid': settingsForm.showError(setting.key, formDir)}">
<div class="col-sm-12">
- <label class="control-label"
+ <label class="col-form-label"
for="{{ setting.key }}">{{ setting.key }}</label>
<input class="form-control"
*ngIf="!isRadio(setting.key)"
<ng-container *ngIf="isRadio(setting.key)">
<br>
- <div class="radio radio-inline">
+ <div class="custom-control custom-radio custom-control-inline">
<input type="radio"
[id]="setting.key + 'Yes'"
value="Yes"
- [formControlName]="setting.key">
- <label [for]="setting.key + 'Yes'">Yes</label>
+ [formControlName]="setting.key"
+ class="custom-control-input">
+ <label class="custom-col-form-label"
+ [for]="setting.key + 'Yes'">Yes</label>
</div>
- <div class="radio radio-inline">
+ <div class="custom-control custom-radio custom-control-inline">
<input type="radio"
[id]="setting.key + 'No'"
value="No"
+ class="custom-control-input"
[formControlName]="setting.key">
- <label [for]="setting.key + 'No'">No</label>
+ <label class="custom-col-form-label"
+ [for]="setting.key + 'No'">No</label>
</div>
</ng-container>
- <span class="help-block">{{ helpText[setting.key]?.help }}</span>
+ <span class="form-text text-muted">{{ helpText[setting.key]?.help }}</span>
</div>
</div>
</div>
[tableActions]="tableActions">
</cd-table-actions>
- <button class="btn btn-sm btn-default btn-label"
+ <button class="btn btn-light"
type="button"
(click)="configureDiscoveryAuth()">
- <i [ngClass]="[icons.key, icons.width]"
+ <i [ngClass]="[icons.key]"
aria-hidden="true">
</i>
<ng-container i18n>Discovery authentication</ng-container>
<ng-template #statusColorTpl
let-value="value">
- <span class="label"
- [ngClass]="{'label-success': 'up' == value, 'label-danger': 'down' == value}">{{ value }}</span>
+ <span class="badge"
+ [ngClass]="{'badge-success': 'up' == value, 'badge-danger': 'down' == value}">{{ value }}</span>
</ng-template>
<ng-template #iscsiSparklineTpl
</ng-template>
<ng-template #syncTmpl>
- <span class="label label-info" i18n>Syncing</span>
+ <span class="badge badge-info" i18n>Syncing</span>
</ng-template>
<ng-template #progressTmpl
});
it('transforms "warning"', () => {
- expect(pipe.transform('warning')).toBe('label label-warning');
+ expect(pipe.transform('warning')).toBe('badge badge-warning');
});
it('transforms "error"', () => {
- expect(pipe.transform('error')).toBe('label label-danger');
+ expect(pipe.transform('error')).toBe('badge badge-danger');
});
it('transforms "success"', () => {
- expect(pipe.transform('success')).toBe('label label-success');
+ expect(pipe.transform('success')).toBe('badge badge-success');
});
it('transforms others', () => {
- expect(pipe.transform('abc')).toBe('label label-info');
+ expect(pipe.transform('abc')).toBe('badge badge-info');
});
});
export class MirrorHealthColorPipe implements PipeTransform {
transform(value: any): any {
if (value === 'warning') {
- return 'label label-warning';
+ return 'badge badge-warning';
} else if (value === 'error') {
- return 'label label-danger';
+ return 'badge badge-danger';
} else if (value === 'success') {
- return 'label label-success';
+ return 'badge badge-success';
}
- return 'label label-info';
+ return 'badge badge-info';
}
}
</p>
<div class="form-group"
- [ngClass]="{'has-error': editModeForm.showError('mirrorMode', formDir)}">
- <label class="control-label"
+ [ngClass]="{':invalid': editModeForm.showError('mirrorMode', formDir)}">
+ <label class="col-form-label"
for="mirrorMode">
<span i18n>Mode</span>
</label>
<option *ngFor="let mirrorMode of mirrorModes"
[value]="mirrorMode.id">{{ mirrorMode.name }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="editModeForm.showError('mirrorMode', formDir, 'cannotDisable')"
i18n>Peer clusters must be removed prior to disabling mirror.</span>
</div>
<div class="modal-body">
<p>
<ng-container i18n>{mode, select, edit {Edit} other {Add}} the pool
- mirror peer attributes for pool <kbd>{{ poolName }}</kbd> and click
+ mirror peer attributes for pool <kbd>{{ poolName }}</kbd> and click
<kbd>Submit</kbd>.</ng-container>
</p>
<div class="form-group"
- [ngClass]="{'has-error': editPeerForm.showError('clusterName', formDir)}">
- <label class="control-label"
+ [ngClass]="{':invalid': editPeerForm.showError('clusterName', formDir)}">
+ <label class="col-form-label"
for="clusterName">
<span i18n>Cluster Name</span>
<span class="required"></span>
name="clusterName"
formControlName="clusterName"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="editPeerForm.showError('clusterName', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="editPeerForm.showError('clusterName', formDir, 'invalidClusterName')"
i18n>The cluster name is not valid.</span>
</div>
<div class="form-group"
- [ngClass]="{'has-error': editPeerForm.showError('clientID', formDir)}">
- <label class="control-label"
+ [ngClass]="{':invalid': editPeerForm.showError('clientID', formDir)}">
+ <label class="col-form-label"
for="clientID">
<span i18n>CephX ID</span>
<span class="required"></span>
id="clientID"
name="clientID"
formControlName="clientID">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="editPeerForm.showError('clientID', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="editPeerForm.showError('clientID', formDir, 'invalidClientID')"
i18n>The CephX ID is not valid.</span>
</div>
<div class="form-group"
- [ngClass]="{'has-error': editPeerForm.showError('monAddr', formDir)}">
- <label class="control-label"
+ [ngClass]="{':invalid': editPeerForm.showError('monAddr', formDir)}">
+ <label class="col-form-label"
for="monAddr">
<span i18n>Monitor Addresses</span>
</label>
id="monAddr"
name="monAddr"
formControlName="monAddr">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="editPeerForm.showError('monAddr', formDir, 'invalidMonAddr')"
i18n>The monitory address is not valid.</span>
</div>
<div class="form-group"
- [ngClass]="{'has-error': editPeerForm.showError('key', formDir)}">
- <label class="control-label"
+ [ngClass]="{':invalid': editPeerForm.showError('key', formDir)}">
+ <label class="col-form-label"
for="key">
<span i18n>CephX Key</span>
</label>
id="key"
name="key"
formControlName="key">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="editPeerForm.showError('key', formDir, 'invalidKey')"
i18n>CephX key must be base64 encoded.</span>
</div>
<fieldset #cfgFormGroup [formGroup]="form.get('configuration')">
<legend i18n>RBD Configuration</legend>
- <div *ngFor="let section of rbdConfigurationService.sections">
- <h3 class="page-header">
+ <div *ngFor="let section of rbdConfigurationService.sections" class="col-12">
+ <h3 class="cd-header">
<span
(click)="toggleSectionVisibility(section.class)"
class="collapsible">{{ section.heading }} <i [ngClass]="!sectionVisibility[section.class] ? icons.addCircle : icons.minusCircle" aria-hidden="true"></i></span>
</h3>
<div class="{{ section.class }}" [hidden]="!sectionVisibility[section.class]">
<div
- class="form-group"
+ class="form-group row"
*ngFor="let option of section.options"
- [ngClass]="{'has-error': form.showError('configuration.' + option.name, cfgFormGroup)}">
+ [ngClass]="{':invalid': form.showError('configuration.' + option.name, cfgFormGroup)}">
<label
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
[for]="option.name">{{ option.displayName }}<cd-helper>{{ option.description }}</cd-helper></label>
<div class="col-sm-9 {{ section.heading }}">
cdIops>
</ng-container>
</ng-container>
- <span class="input-group-btn">
+ <span class="input-group-append">
<button
- class="btn btn-default"
+ class="btn btn-light"
type="button"
data-toggle="button"
[ngClass]="{'active': isDisabled(option.name)}"
</div>
<span
i18n
- class="help-block"
+ class="form-text text-muted"
*ngIf="form.showError('configuration.' + option.name, cfgFormGroup, 'min')">The mininum value is 0</span>
</div>
</div>
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import { ChartsModule } from 'ng2-charts';
import { AlertModule } from 'ngx-bootstrap/alert';
+import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
import { ErrorPanelComponent } from '../../../shared/components/error-panel/error-panel.component';
NgxDatatableModule,
RouterTestingModule,
AlertModule,
+ BsDropdownModule.forRoot(),
ChartsModule,
PipesModule
],
<tbody>
<tr>
<td i18n
- class="bold col-sm-1">Name</td>
- <td class="col-sm-3">{{ selectedItem.name }}</td>
+ class="bold w-25">Name</td>
+ <td class="w-75">{{ selectedItem.name }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Pool</td>
- <td class="col-sm-3">{{ selectedItem.pool_name }}</td>
+ class="bold">Pool</td>
+ <td>{{ selectedItem.pool_name }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Data Pool</td>
- <td class="col-sm-3">{{ selectedItem.data_pool | empty }}</td>
+ class="bold">Data Pool</td>
+ <td>{{ selectedItem.data_pool | empty }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Created</td>
- <td class="col-sm-3">{{ selectedItem.timestamp | cdDate }}</td>
+ class="bold">Created</td>
+ <td>{{ selectedItem.timestamp | cdDate }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Size</td>
- <td class="col-sm-3">{{ selectedItem.size | dimlessBinary }}</td>
+ class="bold">Size</td>
+ <td>{{ selectedItem.size | dimlessBinary }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Objects</td>
- <td class="col-sm-3">{{ selectedItem.num_objs | dimless }}</td>
+ class="bold">Objects</td>
+ <td>{{ selectedItem.num_objs | dimless }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Object size</td>
- <td class="col-sm-3">{{ selectedItem.obj_size | dimlessBinary }}</td>
+ class="bold">Object size</td>
+ <td>{{ selectedItem.obj_size | dimlessBinary }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Features</td>
- <td class="col-sm-3">
+ class="bold">Features</td>
+ <td>
<span *ngFor="let feature of selectedItem.features_name">
- <span class="badge badge-pill badge-primary margin-right-sm">{{ feature }}</span>
+ <span class="badge badge-pill badge-dark mr-2">{{ feature }}</span>
</span>
</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Provisioned</td>
- <td class="col-sm-3">
+ class="bold">Provisioned</td>
+ <td>
<span *ngIf="selectedItem.features_name?.indexOf('fast-diff') === -1">
- <span class="text-muted"
+ <span class="form-text text-muted"
[tooltip]="usageNotAvailableTooltipTpl"
placement="right"
i18n>N/A</span>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Total provisioned</td>
- <td class="col-sm-3">
+ class="bold">Total provisioned</td>
+ <td>
<span *ngIf="selectedItem.features_name?.indexOf('fast-diff') === -1">
- <span class="text-muted"
+ <span class="form-text text-muted"
[tooltip]="usageNotAvailableTooltipTpl"
placement="right"
i18n>N/A</span>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Striping unit</td>
- <td class="col-sm-3">{{ selectedItem.stripe_unit | dimlessBinary }}</td>
+ class="bold">Striping unit</td>
+ <td>{{ selectedItem.stripe_unit | dimlessBinary }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Striping count</td>
- <td class="col-sm-3">{{ selectedItem.stripe_count }}</td>
+ class="bold">Striping count</td>
+ <td>{{ selectedItem.stripe_count }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Parent</td>
- <td class="col-sm-3">
+ class="bold">Parent</td>
+ <td>
<span *ngIf="selectedItem.parent">{{ selectedItem.parent.pool_name }}
/{{ selectedItem.parent.image_name }}
@{{ selectedItem.parent.snap_name }}</span>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Block name prefix</td>
- <td class="col-sm-3">{{ selectedItem.block_name_prefix }}</td>
+ class="bold">Block name prefix</td>
+ <td>{{ selectedItem.block_name_prefix }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Order</td>
- <td class="col-sm-3">{{ selectedItem.order }}</td>
+ class="bold">Order</td>
+ <td>{{ selectedItem.order }}</td>
</tr>
</tbody>
</table>
<div class="col-sm-12 col-lg-6">
<form name="rbdForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="rbdForm"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 i18n="form title|Example: Create Pool@@formTitle"
- class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3>
- </div>
- <div class="panel-body">
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
<!-- Parent -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="rbdForm.getValue('parent')">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="name">{{ action | titlecase }} from</label>
<div class="col-sm-9">
<input class="form-control"
</div>
<!-- Name -->
- <div class="form-group"
- [ngClass]="{'has-error': rbdForm.showError('name', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': rbdForm.showError('name', formDir)}">
+ <label class="col-form-label col-sm-3"
for="name">
<ng-container i18n>Name</ng-container>
<span class="required"></span>
name="name"
formControlName="name"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('name', formDir, 'required')">
<ng-container i18n>This field is required.</ng-container>
</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('name', formDir, 'pattern')">
<ng-container i18n>'/' and '@' are not allowed.</ng-container>
</span>
</div>
<!-- Pool -->
- <div class="form-group"
- [ngClass]="{'has-error': rbdForm.showError('pool', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': rbdForm.showError('pool', formDir)}"
(change)="onPoolChange($event.target.value)">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="pool">
Pool
<span class="required"
[value]="pool.pool_name">{{ pool.pool_name }}</option>
</select>
<span *ngIf="rbdForm.showError('pool', formDir, 'required')"
- class="help-block"
+ class="form-text text-muted"
i18n>This field is required.</span>
</div>
</div>
<!-- Use a dedicated pool -->
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
+ <div class="custom-control custom-checkbox">
<input type="checkbox"
+ class="custom-control-input"
id="useDataPool"
name="useDataPool"
formControlName="useDataPool"
(change)="onUseDataPoolChange()">
- <label i18n
- for="useDataPool">Use a dedicated data pool</label>
+ <label class="custom-control-label"
+ for="useDataPool"
+ i18n>Use a dedicated data pool</label>
</div>
</div>
</div>
<!-- Data Pool -->
- <div class="form-group"
- [ngClass]="{'has-error': rbdForm.showError('dataPool', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': rbdForm.showError('dataPool', formDir)}"
*ngIf="rbdForm.getValue('useDataPool')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="dataPool">
<ng-container i18n>Data pool</ng-container>
<span class="required"
<option *ngFor="let dataPool of dataPools"
[value]="dataPool.pool_name">{{ dataPool.pool_name }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('dataPool', formDir, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Size -->
- <div class="form-group"
- [ngClass]="{'has-error': rbdForm.showError('size', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': rbdForm.showError('size', formDir)}">
+ <label class="col-form-label col-sm-3"
for="size">
<ng-container i18n>Size</ng-container>
<span class="required"></span>
placeholder="e.g., 10GiB"
defaultUnit="GiB"
cdDimlessBinary>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('size', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('size', formDir, 'invalidSizeObject')"
i18n>You have to increase the size.</span>
</div>
</div>
<!-- Features -->
- <div class="form-group"
- [ngClass]="{'has-error': (formDir.submitted || rbdForm.get('features').dirty) && rbdForm.get('features').invalid}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': (formDir.submitted || rbdForm.get('features').dirty) && rbdForm.get('features').invalid}"
formGroupName="features">
<label i18n
- class="col-sm-3 control-label"
+ class="col-sm-3 col-form-label"
for="features">Features</label>
<div class="col-sm-9">
- <div class="checkbox checkbox-primary"
+ <div class="custom-control custom-checkbox"
*ngFor="let feature of featuresList">
<input type="checkbox"
+ class="custom-control-input"
id="{{ feature.key }}"
name="{{ feature.key }}"
formControlName="{{ feature.key }}">
- <label for="{{ feature.key }}">{{ feature.desc }}</label>
+ <label class="custom-control-label"
+ for="{{ feature.key }}">{{ feature.desc }}</label>
<cd-helper *ngIf="feature.helperHtml"
html="{{ feature.helperHtml }}">
</cd-helper>
<!-- Advanced -->
<div class="row">
<div class="col-sm-12">
- <a class="pull-right margin-right-md"
- (click)="advancedEnabled = true"
+ <a class="float-right margin-right-md"
+ (click)="advancedEnabled = true; false"
*ngIf="!advancedEnabled"
+ href=""
i18n>Advanced...</a>
</div>
</div>
+
<div [hidden]="!advancedEnabled">
- <h2 i18n
- class="page-header">Advanced</h2>
+ <legend class="cd-header"
+ i18n>Advanced</legend>
- <div class="section">
- <h3 class="page-header" i18n>Striping</h3>
+ <div class="col-md-12">
+ <h3 class="cd-header"
+ i18n>Striping</h3>
<!-- Object Size -->
- <div class="form-group"
- [ngClass]="{'has-error': rbdForm.showError('obj_size', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': rbdForm.showError('obj_size', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="size">Object size</label>
<div class="col-sm-9">
<select id="obj_size"
</div>
</div>
- <!-- Stripe Unit -->
- <div class="form-group"
- [ngClass]="{'has-error': rbdForm.showError('stripingUnit', formDir)}">
- <label class="control-label col-sm-3"
+ <!-- stripingUnit -->
+ <div class="form-group row"
+ [ngClass]="{':invalid': rbdForm.showError('stripingUnit', formDir)}">
+ <label class="col-form-label col-sm-3"
for="stripingUnit">
<span i18n>Stripe unit</span>
<span class="required"
*ngIf="rbdForm.getValue('stripingCount')">
- </span>
+ </span>
</label>
<div class="col-sm-9">
<select id="stripingUnit"
<option *ngFor="let objectSize of objectSizes"
[value]="objectSize">{{ objectSize }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('stripingUnit', formDir, 'required')"
i18n>This field is required because stripe count is defined!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('stripingUnit', formDir, 'invalidStripingUnit')"
i18n>Stripe unit is greater than object size.</span>
</div>
</div>
<!-- Stripe Count -->
- <div class="form-group"
- [ngClass]="{'has-error': rbdForm.showError('stripingCount', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': rbdForm.showError('stripingCount', formDir)}">
+ <label class="col-form-label col-sm-3"
for="stripingCount">
<span i18n>Stripe count</span>
<span class="required"
*ngIf="rbdForm.getValue('stripingUnit')">
- </span>
+ </span>
</label>
<div class="col-sm-9">
<input id="stripingCount"
formControlName="stripingCount"
class="form-control"
type="number">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('stripingCount', formDir, 'required')"
i18n>This field is required because stripe unit is defined!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="rbdForm.showError('stripingCount', formDir, 'min')"
i18n>Stripe count must be greater than 0.</span>
</div>
</div>
</div>
- <div class="section">
- <cd-rbd-configuration-form [form]="rbdForm"
- [initializeData]="initializeConfigData"
- (changes)="getDirtyConfigurationValues = $event"></cd-rbd-configuration-form>
- </div>
-
+ <cd-rbd-configuration-form [form]="rbdForm"
+ [initializeData]="initializeConfigData"
+ (changes)="getDirtyConfigurationValues = $event"></cd-rbd-configuration-form>
</div>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
- <cd-submit-button
- [form]="formDir"
- (submitAction)="submit()"
- i18n="form action button|Example: Create Pool@@formActionButton"
- type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="submit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="formDir">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
describe('test image configuration component', () => {
it('is visible', () => {
fixture.detectChanges();
- expect(queryNativeElement('cd-rbd-configuration-form').parentElement.hidden).toBe(false);
+ expect(
+ fixture.debugElement.query(By.css('cd-rbd-configuration-form')).nativeElement.parentElement
+ .hidden
+ ).toBe(true);
});
});
<div class="modal-header">
- <h4 class="modal-title pull-left"
+ <h4 class="modal-title float-left"
i18n>{ editing, select, true {Rename} other {Create}} RBD Snapshot</h4>
<button type="button"
- class="close pull-right"
+ class="close float-right"
aria-label="Close"
(click)="modalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
<form name="snapshotForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="snapshotForm"
novalidate>
<div class="modal-body">
<!-- Name -->
- <div class="form-group"
- [ngClass]="{'has-error': snapshotForm.showError('snapshotName', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': snapshotForm.showError('snapshotName', formDir)}">
+ <label class="col-form-label col-sm-3"
for="snapshotName">
<ng-container i18n>Name</ng-container>
<span class="required"></span>
name="snapshotName"
formControlName="snapshotName"
autofocus>
- <span class="help-block"
- *ngIf="snapshotForm.showError('snapshotName', formDir, 'required')"
+ <span class="form-text text-muted"
+ *ngIf="snapshotForm.showError('snapshotName', formDir, 'required')">
i18n>This field is required.</span>
</div>
</div>
<ng-template #protectTpl
let-value="value">
<span *ngIf="value"
- class="label label-success"
+ class="badge badge-success">
i18n>PROTECTED</span>
<span *ngIf="!value"
- class="label label-info"
+ class="badge badge-info"
i18n>UNPROTECTED</span>
</ng-template>
[tableActions]="tableActions">
</cd-table-actions>
- <button class="btn btn-sm btn-default btn-label"
+ <button class="btn btn-light"
type="button"
(click)="purgeModal()"
*ngIf="permission.delete">
- <i [ngClass]="[icons.destroy, icons.width]"
+ <i [ngClass]="[icons.destroy]"
aria-hidden="true"></i>
<ng-container i18n>Purge Trash</ng-container>
</button>
click <kbd>Move Image</kbd>. Optionally, you can pick an expiration date.</p>
<div class="form-group"
- [ngClass]="{'has-error': moveForm.showError('expiresAt', formDir)}">
+ [ngClass]="{':invalid': moveForm.showError('expiresAt', formDir)}">
<label for="expires"
i18n>Protection expires at</label>
<input type="text"
[bsConfig]="bsConfig"
formControlName="expiresAt"
bsDatepicker>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="moveForm.showError('expiresAt', formDir, 'format')"
i18n>Wrong date format. Please use "YYYY-MM-DD HH:mm:ss".</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="moveForm.showError('expiresAt', formDir, 'expired')"
i18n>Protection has already expired. Please pick a future date or leave it empty.</span>
</div>
</p>
<div class="form-group">
- <label class="center-block"
+ <label class="mx-auto"
i18n>Pool:</label>
<input class="form-control"
type="text"
</p>
<div class="form-group"
- [ngClass]="{'has-error': restoreForm.showError('name', formDir)}">
+ [ngClass]="{':invalid': restoreForm.showError('name', formDir)}">
<label for="name"
i18n>New Name</label>
<input type="text"
autocomplete="off"
formControlName="name"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="restoreForm.showError('name', formDir, 'required')"
i18n>This field is required.</span>
</div>
</tab>
<tab i18n-heading
heading="Clients: {{ clientCount }}"
- (select)="clientsSelect=true"
+ (selectTab)="clientsSelect=true"
(deselect)="clientsSelect=false">
<cd-cephfs-clients [id]="id"
*ngIf="clientsSelect">
<tbody>
<tr>
<td i18n
- class="bold col-sm-1">Name</td>
- <td class="col-sm-3">{{ selectedItem.name }}</td>
+ class="bold w-25">Name</td>
+ <td class="w-75">{{ selectedItem.name }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Description</td>
- <td class="col-sm-3">{{ selectedItem.desc }}</td>
+ class="bold">Description</td>
+ <td>{{ selectedItem.desc }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Long description</td>
- <td class="col-sm-3">{{ selectedItem.long_desc }}</td>
+ class="bold">Long description</td>
+ <td>{{ selectedItem.long_desc }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Current values</td>
- <td class="col-sm-3">
+ class="bold">Current values</td>
+ <td>
<span *ngFor="let conf of selectedItem.value; last as isLast">
- {{ conf.section }}: {{ conf.value }}{{ !isLast ? "," : "" }}<br/>
+ {{ conf.section }}: {{ conf.value }}{{ !isLast ? "," : "" }}<br />
</span>
</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Default</td>
- <td class="col-sm-3">{{ selectedItem.default }}</td>
+ class="bold">Default</td>
+ <td>{{ selectedItem.default }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Daemon default</td>
- <td class="col-sm-3">{{ selectedItem.daemon_default }}</td>
+ class="bold">Daemon default</td>
+ <td>{{ selectedItem.daemon_default }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Type</td>
- <td class="col-sm-3">{{ selectedItem.type }}</td>
+ class="bold">Type</td>
+ <td>{{ selectedItem.type }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Min</td>
- <td class="col-sm-3">{{ selectedItem.min }}</td>
+ class="bold">Min</td>
+ <td>{{ selectedItem.min }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Max</td>
- <td class="col-sm-3">{{ selectedItem.max }}</td>
+ class="bold">Max</td>
+ <td>{{ selectedItem.max }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Flags</td>
- <td class="col-sm-3">
+ class="bold">Flags</td>
+ <td>
<span *ngFor="let flag of selectedItem.flags">
<span title="{{ flags[flag] }}">
- <span class="badge badge-pill badge-primary margin-right-sm">{{ flag | uppercase }}</span>
+ <span class="badge badge-pill badge-dark mr-2">{{ flag | uppercase }}</span>
</span>
</span>
</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Services</td>
- <td class="col-sm-3">
+ class="bold">Services</td>
+ <td>
<span *ngFor="let service of selectedItem.services">
- <span class="badge badge-pill badge-primary margin-right-sm">{{ service }}</span>
+ <span class="badge badge-pill badge-dark mr-2">{{ service }}</span>
</span>
</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Source</td>
- <td class="col-sm-3">{{ selectedItem.source }}</td>
+ class="bold">Source</td>
+ <td>{{ selectedItem.source }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Level</td>
- <td class="col-sm-3">{{ selectedItem.level }}</td>
+ class="bold">Level</td>
+ <td>{{ selectedItem.level }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Can be updated at runtime (editable)</td>
- <td class="col-sm-3">{{ selectedItem.can_update_at_runtime | booleanText }}</td>
+ class="bold">Can be updated at runtime (editable)</td>
+ <td>{{ selectedItem.can_update_at_runtime | booleanText }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Tags</td>
- <td class="col-sm-3">{{ selectedItem.tags }}</td>
+ class="bold">Tags</td>
+ <td>{{ selectedItem.tags }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Enum values</td>
- <td class="col-sm-3">{{ selectedItem.enum_values }}</td>
+ class="bold">Enum values</td>
+ <td>{{ selectedItem.enum_values }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">See also</td>
- <td class="col-sm-3">{{ selectedItem.see_also }}</td>
+ class="bold">See also</td>
+ <td>{{ selectedItem.see_also }}</td>
</tr>
</tbody>
</table>
-<div class="col-sm-12 col-lg-6">
+<div class="col-sm-12 col-md-12 col-lg-6">
<form name="configForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="configForm"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">
- <ng-container i18n>Edit</ng-container> {{ configForm.getValue('name') }}
- </h3>
+ <div class="card">
+ <div class="card-header">
+ <ng-container i18>Edit</ng-container> {{ configForm.getValue('name') }}
</div>
- <div class="panel-body">
+ <div class="card-body">
<!-- Name -->
- <div class="form-group">
+ <div class="form-group row">
<label i18n
- class="control-label col-sm-3">Name</label>
+ class="col-form-label col-sm-3">Name</label>
<div class="col-sm-9">
<input class="form-control"
type="text"
</div>
<!-- Description -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="configForm.getValue('desc')">
<label i18n
- class="control-label col-sm-3">Description</label>
+ class="col-form-label col-sm-3">Description</label>
<div class="col-sm-9">
<textarea class="form-control resize-vertical"
id="desc"
</div>
<!-- Long description -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="configForm.getValue('long_desc')">
<label i18n
- class="control-label col-sm-3">Long description</label>
+ class="col-form-label col-sm-3">Long description</label>
<div class="col-sm-9">
<textarea class="form-control resize-vertical"
id="long_desc"
</div>
<!-- Default -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="configForm.getValue('default') !== ''">
<label i18n
- class="control-label col-sm-3">Default</label>
+ class="col-form-label col-sm-3">Default</label>
<div class="col-sm-9">
<input class="form-control"
type="text"
</div>
<!-- Daemon default -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="configForm.getValue('daemon_default') !== ''">
<label i18n
- class="control-label col-sm-3">Daemon default</label>
+ class="col-form-label col-sm-3">Daemon default</label>
<div class="col-sm-9">
<input class="form-control"
type="text"
</div>
<!-- Services -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="configForm.getValue('services').length > 0">
<label i18n
- class="control-label col-sm-3">Services</label>
+ class="col-form-label col-sm-3">Services</label>
<div class="col-sm-9">
<span *ngFor="let service of configForm.getValue('services')"
class="form-component-badge">
- <span class="badge badge-pill badge-primary">{{ service }}</span>
+ <span class="badge badge-pill badge-dark">{{ service }}</span>
</span>
</div>
</div>
<!-- Values -->
- <div class="col-sm-12"
- formGroupName="values">
+ <div formGroupName="values">
<h2 i18n
- class="page-header">Values</h2>
- <div class="row"
- *ngFor="let section of availSections">
- <div class="form-group"
+ class="cd-header">Values</h2>
+ <ng-container *ngFor="let section of availSections">
+ <div class="form-group row"
*ngIf="type === 'bool'">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input [id]="section"
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ [id]="section"
type="checkbox"
[formControlName]="section">
- <label [for]="section">{{ section }}
+ <label class="form-check-label"
+ [for]="section">{{ section }}
</label>
</div>
</div>
</div>
- <div class="form-group"
- [ngClass]="{'has-error': configForm.showError(section, formDir)}"
+
+ <div class="form-group row"
+ [ngClass]="{':invalid': configForm.showError(section, formDir)}"
*ngIf="type !== 'bool'">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
[for]="section">{{ section }}
</label>
<div class="col-sm-9">
[placeholder]="humanReadableType"
[formControlName]="section"
[step]="getStep(type, this.configForm.getValue(section))">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="configForm.showError(section, formDir, 'pattern')">
{{ patternHelpText }}
</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="configForm.showError(section, formDir, 'invalidUuid')">
{{ patternHelpText }}
</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="configForm.showError(section, formDir, 'max')"
i18n>The entered value is too high! It must not be greater than {{ maxValue }}.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="configForm.showError(section, formDir, 'min')"
i18n>The entered value is too low! It must not be lower than {{ minValue }}.</span>
</div>
</div>
- </div>
+ </ng-container>
</div>
</div>
<!-- Footer -->
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
<cd-submit-button [form]="formDir"
- type="button"
(submitAction)="submit()">
<span i18n>Save</span>
</cd-submit-button>
[selection]="selection"
[tableActions]="tableActions">
</cd-table-actions>
- <div class="table-filters">
+ <div class="table-filters form-inline">
<div class="form-group filter"
*ngFor="let filter of filters">
<label>{{ filter.label }}: </label>
- <select class="form-control input-sm"
+ <select class="form-control"
[(ngModel)]="filter.value"
(ngModelChange)="updateFilter()">
<option *ngFor="let opt of filter.options">{{ opt }}</option>
</select>
</div>
- <a [ngClass]="[icons.stack]"
- title="Reset filters"
- (click)="resetFilter()">
- <i [ngClass]="[icons.filter, icons.stack2x]"></i>
- <i [ngClass]="[icons.destroy, icons.stack1x]" style="margin-left: 8px; margin-top: 5px;"></i>
- </a>
+
+ <div class="widget-toolbar tc_refreshBtn">
+ <button type="button"
+ title="Reset filters"
+ class="btn btn-light"
+ (click)="resetFilter()">
+ <span [ngClass]="[icons.stack]">
+ <i [ngClass]="[icons.filter, icons.stack2x]"></i>
+ <i [ngClass]="[icons.destroy, icons.stack1x]"
+ style="margin-left: 8px; margin-top: 5px;"></i>
+ </span>
+ </button>
+ </div>
</div>
<cd-configuration-details cdTableDetail
[selection]="selection">
</cd-configuration-details>
</cd-table>
-<ng-template #confValTpl let-value="value">
+<ng-template #confValTpl
+ let-value="value">
<span *ngIf="value">
<span *ngFor="let conf of value; last as isLast">
- {{ conf.section }}: {{ conf.value }}{{ !isLast ? "," : "" }}<br/>
+ {{ conf.section }}: {{ conf.value }}{{ !isLast ? "," : "" }}<br />
</span>
</span>
</ng-template>
padding-right: 8px;
}
+.fa-stack {
+ font-size: 0.79rem;
+}
+
::ng-deep datatable-body-cell.wrap {
word-break: break-all;
}
<div class="row">
<div class="col-sm-12 col-lg-12">
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">
- <span i18n>CRUSH map viewer</span>
- </h3>
- </div>
- <div class="panel-body">
- <div class="col-sm-6 col-lg-6">
- <tree [tree]="tree"
- [settings]="{rootIsVisible: false}"
- (nodeSelected)="onNodeSelected($event)">
- <ng-template let-node>
- <span class="label"
- [ngClass]="{'label-success': ['in', 'up'].includes(node.status), 'label-danger': ['down', 'out'].includes(node.status)}">{{ node.status }}</span>
- <span> </span>
- <span class="node-name" [innerHTML]="node.value"></span>
- </ng-template>
- </tree>
- </div>
- <div class="col-sm-6 col-lg-6 metadata" *ngIf="metadata">
- <legend>{{ metadataTitle }}</legend>
- <cd-table-key-value [data]="metadata"></cd-table-key-value>
+ <div class="card">
+ <div class="card-header"
+ i18n>CRUSH map viewer</div>
+ <div class="card-body">
+ <div class="row">
+ <div class="col-sm-6 col-lg-6">
+ <tree [tree]="tree"
+ [settings]="{rootIsVisible: false}"
+ (nodeSelected)="onNodeSelected($event)">
+ <ng-template let-node>
+ <span class="badge"
+ [ngClass]="{'badge-success': ['in', 'up'].includes(node.status), 'badge-danger': ['down', 'out'].includes(node.status)}">
+ {{ node.status }}
+ </span>
+ <span> </span>
+ <span class="node-name"
+ [innerHTML]="node.value"></span>
+ </ng-template>
+ </tree>
+ </div>
+ <div class="col-sm-6 col-lg-6 metadata"
+ *ngIf="metadata">
+ <legend>{{ metadataTitle }}</legend>
+ <cd-table-key-value [data]="metadata"></cd-table-key-value>
+ </div>
</div>
</div>
</div>
</div>
-</div>
it('should display right title', () => {
fixture.detectChanges();
- const span = debugElement.nativeElement.querySelector('span');
+ const span = debugElement.nativeElement.querySelector('.card-header');
expect(span.textContent).toBe('CRUSH map viewer');
});
<div *ngIf="contentData">
-<ng-container *ngTemplateOutlet="logFiltersTpl"></ng-container>
-<tabset>
- <tab i18n-heading
- heading="Cluster Logs">
- <div class="well">
- <div *ngIf="clog">
- <p *ngFor="let line of clog">
- <span class="timestamp">{{ line.stamp | cdDate }}</span>
- <span class="priority {{ line.priority | logPriority }}">{{ line.priority }}</span>
- <span class="message">{{ line.message }}</span>
- </p>
- </div>
- <div *ngIf="contentData.clog.length === 0">
- <p i18n>No entries found</p>
- </div>
- </div>
- </tab>
+ <ng-container *ngTemplateOutlet="logFiltersTpl"></ng-container>
- <tab i18n-heading
- heading="Audit Logs">
- <div class="well">
- <div *ngIf="audit_log">
- <p *ngFor="let line of audit_log">
- <span class="timestamp">{{ line.stamp | cdDate }}</span>
- <span class="priority {{ line.priority | logPriority }}">{{ line.priority }}</span>
- <span class="message">{{ line.message }}</span>
- </p>
- </div>
- <div *ngIf="contentData.audit_log.length === 0">
- <p i18n>No entries found</p>
- </div>
- </div>
- </tab>
-</tabset>
+ <tabset>
+ <tab i18n-heading
+ heading="Cluster Logs">
+ <div class="card bg-light mb-3"
+ *ngIf="clog">
+ <div class="card-body">
+ <p *ngFor="let line of clog">
+ <span class="timestamp">{{ line.stamp | cdDate }}</span>
+ <span class="priority {{ line.priority | logPriority }}">{{ line.priority }}</span>
+ <span class="message">{{ line.message }}</span>
+ </p>
+
+ <span *ngIf="contentData.clog.length === 0"
+ i18n>No entries found</span>
+ </div>
+ </div>
+ </tab>
+
+ <tab i18n-heading
+ heading="Audit Logs">
+ <div class="card bg-light mb-3"
+ *ngIf="audit_log">
+ <div class="card-body">
+ <p *ngFor="let line of audit_log">
+ <span class="timestamp">{{ line.stamp | cdDate }}</span>
+ <span class="priority {{ line.priority | logPriority }}">{{ line.priority }}</span>
+ <span class="message">{{ line.message }}</span>
+ </p>
+
+ <span *ngIf="contentData.audit_log.length === 0"
+ i18n>No entries found</span>
+ </div>
+ </div>
+ </tab>
+ </tabset>
</div>
<ng-template #logFiltersTpl>
- <div class="row log-filters">
- <div class="col-xs-4 col-md-2 cd-col-1 filter-box">
+ <div class="form-inline">
+ <div class="form-group">
<label i18n>Priority:</label>
<select class="form-control"
[(ngModel)]="priority"
(ngModelChange)="filterLogs()">
- <option class="form-control"
- *ngFor="let prio of prioritys"
+ <option *ngFor="let prio of prioritys"
[value]="prio.value">{{ prio.name }}</option>
</select>
</div>
- <div class="col-xs-4 col-md-3 cd-col-3 filter-box">
+
+ <div class="form-group">
<label i18n>Keyword:</label>
<div class="input-group">
- <span class="input-group-addon">
- <i [ngClass]="[icons.search]"></i>
- </span>
+ <div class="input-group-prepend">
+ <span class="input-group-text">
+ <i [ngClass]="[icons.search]"></i>
+ </span>
+ </div>
+
<input class="form-control"
type="text"
[(ngModel)]="search"
(keyup)="filterLogs()">
- <span class="input-group-btn">
+
+ <div class="input-group-append">
<button type="button"
- class="btn btn-default clear-input tc_clearInputBtn"
+ class="btn btn-light"
(click)="clearSearchKey()">
<i class="icon-prepend {{ icons.destroy }}"></i>
</button>
- </span>
+ </div>
</div>
</div>
- <div class="col-xs-4 col-md-3 cd-col-2 filter-box">
+
+ <div class="form-group">
<label i18n>Date:</label>
<div class="input-group">
<input type="text"
bsDatepicker
[(ngModel)]="selectedDate"
(ngModelChange)="filterLogs()">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default clear-input tc_clearInputBtn"
+ class="btn btn-light"
(click)="clearDate()">
<i class="icon-prepend {{ icons.destroy }}"></i>
</button>
</span>
</div>
</div>
- <div class="clearfix visible-xs-block"></div>
- <div class="col-xs-8 col-md-4 cd-col-4 filter-box time-box">
+
+ <div class="form-group">
<label i18n>Time range:</label>
- <timepicker [showMeridian]="false"
- [showSpinners]="showSpinners"
- [minuteStep]="1"
- [(ngModel)]="startTime"
- (ngModelChange)="filterLogs()">
- </timepicker>
- <span> — </span>
- <timepicker [showMeridian]="false"
- [showSpinners]="showSpinners"
- [minuteStep]="1"
- [(ngModel)]="endTime"
- (ngModelChange)="filterLogs()">
- </timepicker>
+ <div class="d-inline-flex">
+ <timepicker [showMeridian]="false"
+ [showSpinners]="false"
+ [minuteStep]="1"
+ [(ngModel)]="startTime"
+ (ngModelChange)="filterLogs()">
+ </timepicker>
+ <span class="middle"> — </span>
+ <timepicker [showMeridian]="false"
+ [showSpinners]="false"
+ [minuteStep]="1"
+ [(ngModel)]="endTime"
+ (ngModelChange)="filterLogs()">
+ </timepicker>
+ </div>
</div>
</div>
</ng-template>
-@import '../../../../defaults';
+@import 'styles';
p {
font-family: monospace;
- color: black;
}
-.well {
+.card {
div p {
display: flex;
}
::ng-deep timepicker table tbody tr td {
- .bs-timepicker-field {
- width: 3.5rem;
+ input.bs-timepicker-field {
+ width: 3.5rem !important;
font-size: 1rem;
padding: 4px 6px;
}
- .btn {
- font-size: 1rem;
- }
}
-.log-filters {
- margin-bottom: 5px;
- padding: 0 30px;
- * {
- box-sizing: border-box;
- }
-
- .filter-box {
- margin: 0;
- padding: 0 15px 5px 0;
- display: -webkit-flex;
- display: flex;
- justify-content: flex-start;
- align-items: center;
- label {
- padding-top: 5px;
- padding-right: 5px;
- }
- }
-
- @media (max-width: 991px) {
- .time-box {
- margin-top: 20px;
- }
- }
-
- @media (min-width: 1200px) {
- .cd-col-4 {
- width: 28vw;
- }
-
- .cd-col-3 {
- width: 20vw;
- }
-
- .cd-col-2 {
- width: 16vw;
- }
- .cd-col-1 {
- width: 14vw;
- }
- }
-
- @media (min-width: 1400px) {
- .cd-col-4 {
- width: 24vw;
- }
-
- .cd-col-3 {
- width: 18vw;
- }
-
- .cd-col-2 {
- width: 14vw;
- }
- .cd-col-1 {
- width: 12vw;
- }
- }
-
- @media (min-width: 1600px) {
- .cd-col-4 {
- width: 22vw;
- }
-
- .cd-col-3 {
- width: 16vw;
- }
-
- .cd-col-2 {
- width: 12vw;
- }
- .cd-col-1 {
- width: 10vw;
- }
- }
+label {
+ @extend .mr-2;
+}
- @media (min-width: 1800px) {
- .cd-col-3 {
- width: 14vw;
- }
+.form-group {
+ @extend .mr-3;
+ @extend .mb-3;
+}
- .cd-col-2 {
- width: 11vw;
- }
- .cd-col-1 {
- width: 9vw;
- }
- }
+.middle {
+ padding-top: 7px;
}
<div class="col-sm-12 col-lg-6"
*ngIf="!loading && !error">
<form name="mgrModuleForm"
- class="form-horizontal"
#frm="ngForm"
[formGroup]="mgrModuleForm"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title" i18n>Edit Manager module</h3>
- </div>
- <div class="panel-body">
- <div class="form-group"
- [ngClass]="{'has-error': mgrModuleForm.showError(moduleOption.value.name, frm)}"
+ <div class="card">
+ <div class="card-header"
+ i18n>Edit Manager module</div>
+ <div class="card-body">
+ <div class="form-group row"
+ [ngClass]="{':invalid': mgrModuleForm.showError(moduleOption.value.name, frm)}"
*ngFor="let moduleOption of moduleOptions | keyvalue">
<!-- Field label -->
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="{{ moduleOption.value.name }}">
{{ moduleOption.value.name }}
<cd-helper *ngIf="moduleOption.value.long_desc || moduleOption.value.desc">
{{ value }}
</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'invalidUuid')"
i18n>The entered value is not a valid UUID, e.g.: 67dcac9f-2c03-4d6c-b7bd-1210b3a259a8</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'pattern')"
i18n>The entered value needs to be a valid IP address.</span>
</div>
formControlName="{{ moduleOption.value.name }}"
min="{{ moduleOption.value.min }}"
max="{{ moduleOption.value.max }}">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'max')"
i18n>The entered value is too high! It must be lower or equal to {{ moduleOption.value.max }}.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'min')"
i18n>The entered value is too low! It must be greater or equal to {{ moduleOption.value.min }}.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'pattern')"
i18n>The entered value needs to be a number.</span>
</div>
class="form-control"
type="number"
formControlName="{{ moduleOption.value.name }}">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="mgrModuleForm.showError(moduleOption.value.name, frm, 'pattern')"
i18n>The entered value needs to be a number or decimal.</span>
</div>
</div>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
- <cd-submit-button type="button"
- (submitAction)="onSubmit()"
+ <cd-submit-button (submitAction)="onSubmit()"
[form]="mgrModuleForm">
<ng-container i18n>Update</ng-container>
</cd-submit-button>
<button type="button"
- class="btn btn-sm btn-default"
+ class="btn btn-light"
routerLink="/mgr-modules"
i18n>Back</button>
</div>
<div class="row">
- <div class="col-md-4">
+ <div class="col-lg-4">
<fieldset>
- <legend i18n>Status</legend>
+ <legend class="cd-header" i18n>Status</legend>
<table class="table table-striped"
*ngIf="mon_status">
<tr>
</fieldset>
</div>
- <div class="col-md-8">
+ <div class="col-lg-8">
<legend i18n
- class="in-quorum">In Quorum</legend>
+ class="in-quorum cd-header">In Quorum</legend>
<cd-table [data]="inQuorum.data"
[columns]="inQuorum.columns">
</cd-table>
<legend i18n
- class="in-quorum">Not In Quorum</legend>
+ class="in-quorum cd-header">Not In Quorum</legend>
<cd-table [data]="notInQuorum.data"
(fetchData)="refresh()"
[columns]="notInQuorum.columns">
[formGroup]="osdFlagsForm"
novalidate>
<div class="modal-body osd-modal">
- <div class="checkbox checkbox-primary"
+ <div class="form-check abc-checkbox abc-checkbox-primary"
*ngFor="let flag of flags; let last = last">
- <input type="checkbox"
+ <input class="form-check-input"
+ type="checkbox"
[checked]="flag.value"
(change)="flag.value = !flag.value"
[name]="flag.code"
[id]="flag.code"
[disabled]="flag.disabled">
- <label [for]="flag.code"
+ <label class="form-check-label"
+ [for]="flag.code"
ng-class="['tc_' + key]">
<strong>{{ flag.name }}</strong>
<br>
- <span class="text-muted">{{ flag.description }}</span>
+ <span class="form-text text-muted">{{ flag.description }}</span>
</label>
<hr class="oa-hr-small"
*ngIf="!last">
margin: 5px;
}
}
+
+.abc-checkbox label::before {
+ margin-top: 3px;
+}
<cd-table-actions [permission]="{read: true}"
[selection]="selection"
dropDownOnly="Cluster-wide configuration"
- btnColor="default"
+ btnColor="light"
class="btn-group"
id="cluster-wide-actions"
[tableActions]="clusterWideActions">
<ng-template #statusColor
let-value="value">
<span *ngFor="let state of value; last as last">
- <span class="label"
- [ngClass]="{'label-success': ['in', 'up'].includes(state), 'label-danger': ['down', 'out'].includes(state)}">{{ state }}</span>
+ <span class="badge"
+ [ngClass]="{'badge-success': ['in', 'up'].includes(state), 'badge-danger': ['down', 'out'].includes(state)}">{{ state }}</span>
<span *ngIf="!last"> </span>
</span>
</ng-template>
<ng-template #markOsdConfirmationTpl
let-markActionDescription="markActionDescription">
<ng-container i18n><strong>OSD {{ selection.first().id }}</strong> will be marked
- <strong>{{ markActionDescription }}</strong> if you proceed.</ng-container>
+<strong>{{ markActionDescription }}</strong> if you proceed.</ng-container>
</ng-template>
<ng-template #criticalConfirmationTpl
<cd-warning-panel i18n>The OSD is not safe to destroy!</cd-warning-panel>
</div>
<ng-container i18n><strong>OSD {{ selection.first().id }}</strong> will be
- <strong>{{ actionDescription }}</strong> if you proceed.</ng-container>
+<strong>{{ actionDescription }}</strong> if you proceed.</ng-container>
</ng-template>
const tableActionElement = fixture.debugElement.query(By.directive(TableActionsComponent));
const toClassName = TestBed.get(TableActionsComponent).toClassName;
const getActionClasses = (action: CdTableAction) =>
- tableActionElement.query(By.css('.' + toClassName(action.name))).classes;
+ tableActionElement.query(By.css(`.${toClassName(action.name)} .dropdown-item`)).classes;
component.tableActions.forEach((action) => {
expect(getActionClasses(action).disabled).toBe(true);
class="modal-title">{{ action | titlecase }} {{ resource | upperFirst }}</ng-container>
<ng-container class="modal-content">
- <form class="form-horizontal"
- #formDir="ngForm"
+ <form #formDir="ngForm"
[formGroup]="osdPgScrubForm"
novalidate>
<div class="modal-body osd-modal">
<div class="button-group text-right">
<cd-submit-button *ngIf="permissions.configOpt.update"
(submitAction)="submitAction()"
- [form]="osdPgScrubForm"
i18n="form action button|Example: Create Pool@@formActionButton"
- type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ [form]="osdPgScrubForm">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button [back]="bsModalRef.hide">
</cd-back-button>
</div>
i18n>OSD Recovery Priority</ng-container>
<ng-container class="modal-content">
- <form class="form-horizontal"
- #formDir="ngForm"
+ <form #formDir="ngForm"
[formGroup]="osdRecvSpeedForm"
novalidate>
<div class="modal-body">
<!-- Priority -->
- <div class="form-group"
- [ngClass]="{'has-error': osdRecvSpeedForm.showError('priority', formDir)}">
- <label class="control-label col-sm-6"
+ <div class="form-group row"
+ [ngClass]="{':invalid': osdRecvSpeedForm.showError('priority', formDir)}">
+ <label class="col-form-label col-sm-6"
for="priority">
<ng-container i18n>Priority</ng-container>
<span class="required"></span>
{{ priority.text }}
</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="osdRecvSpeedForm.showError('priority', formDir, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Customize priority -->
- <div class="form-group">
- <div class="col-sm-offset-6 col-sm-6">
- <div class="checkbox checkbox-primary">
+ <div class="form-group row">
+ <div class="offset-sm-6 col-sm-6">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
<input formControlName="customizePriority"
+ class="form-check-input"
id="customizePriority"
+ name="customizePriority"
type="checkbox"
(change)="onCustomizePriorityChange()">
- <label i18n
- for="customizePriority">Customize priority values</label>
+ <label class="form-check-label"
+ for="customizePriority"
+ i18n>Customize priority values</label>
</div>
</div>
</div>
<!-- Priority values -->
- <div class="form-group" *ngFor="let attr of priorityAttrs | keyvalue"
- [ngClass]="{'has-error': osdRecvSpeedForm.getValue('customizePriority') &&
+ <div class="form-group row"
+ *ngFor="let attr of priorityAttrs | keyvalue"
+ [ngClass]="{':invalid': osdRecvSpeedForm.getValue('customizePriority') &&
osdRecvSpeedForm.showError(attr.key, formDir)}">
- <label class="control-label col-sm-6"
+ <label class="col-form-label col-sm-6"
[for]="attr.key">{{ attr.value.text }}
<cd-helper *ngIf="attr.value.desc">{{ attr.value.desc }}</cd-helper>
- <span class="required" *ngIf="osdRecvSpeedForm.getValue('customizePriority')"></span>
+ <span class="required"
+ *ngIf="osdRecvSpeedForm.getValue('customizePriority')"></span>
</label>
<div class="col-sm-6">
<input class="form-control"
[id]="attr.key"
[formControlName]="attr.key"
[readonly]="!osdRecvSpeedForm.getValue('customizePriority')">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="osdRecvSpeedForm.getValue('customizePriority') &&
osdRecvSpeedForm.showError(attr.key, formDir, 'required')"
i18n>This field is required!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="osdRecvSpeedForm.getValue('customizePriority') &&
osdRecvSpeedForm.showError(attr.key, formDir, 'pattern')"
i18n>{{ attr.value.patternHelpText }}</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="osdRecvSpeedForm.getValue('customizePriority') &&
osdRecvSpeedForm.showError(attr.key, formDir, 'max')"
i18n>The entered value is too high! It must not be greater than {{ attr.value.maxValue }}.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="osdRecvSpeedForm.getValue('customizePriority') &&
osdRecvSpeedForm.showError(attr.key, formDir, 'min')"
i18n>The entered value is too low! It must not be lower than {{ attr.value.minValue }}.</span>
i18n>Reweight OSD</ng-container>
<ng-container class="modal-content">
- <form class="form-horizontal"
- [formGroup]="reweightForm">
- <div class="modal-body" [ngClass]="{'has-error': weight.errors}">
+ <form [formGroup]="reweightForm">
+ <div class="modal-body" [ngClass]="{':invalid': weight.errors}">
<div class="row">
- <label for="weight" class="col-sm-2 control-label">Weight</label>
+ <label for="weight" class="col-sm-2 col-form-label">Weight</label>
<div class="col-sm-10">
<input id="weight" class="form-control" type="number"
step="0.1" formControlName="weight" min="0" max="1"
[value]="currentWeight">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="weight.errors">
<span *ngIf="weight.errors?.required"
i18n>This field is required.</span>
<ng-container class="modal-content">
<form name="scrubForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="scrubForm"
novalidate>
selection = new CdTableSelection();
icons = Icons;
customCss = {
- 'label label-danger': 'active',
- 'label label-warning': 'unprocessed',
- 'label label-info': 'suppressed'
+ 'badge badge-danger': 'active',
+ 'badge badge-warning': 'unprocessed',
+ 'badge badge-info': 'suppressed'
};
constructor(
<tab heading="Alerts"
i18n-heading
[active]="url === '/alerts'"
- (select)="navigateTo('/alerts')">
+ (selectTab)="navigateTo('/alerts')">
</tab>
<tab heading="Silences"
i18n-heading
[active]="url === '/silence'"
- (select)="navigateTo('/silence')">
+ (selectTab)="navigateTo('/silence')">
</tab>
</tabset>
let router: Router;
const selectTab = (index) => {
- fixture.debugElement.queryAll(By.css('tab'))[index].triggerEventHandler('select', null);
+ fixture.debugElement.queryAll(By.css('tab'))[index].triggerEventHandler('selectTab', null);
};
configureTestBed({
-<ng-template #matcherTpl let-matcher="matcher" let-index="index">
- <div class="input-group">
+<ng-template #matcherTpl
+ let-matcher="matcher"
+ let-index="index">
+ <div class="input-group my-2">
<ng-container *ngFor="let config of matcherConfig">
- <span class="input-group-addon"
- [tooltip]=config.tooltip>
- <i class="icon-prepend" [ngClass]="[config.icon]"></i>
- </span>
+ <div class="input-group-prepend">
+ <span class="input-group-text"
+ [tooltip]=config.tooltip>
+ <i [ngClass]="[config.icon]"></i>
+ </span>
+ </div>
+
<ng-container *ngIf="config.attribute !== 'isRegex'">
<input type="text"
id="matcher-{{config.attribute}}-{{index}}"
disabled
readonly>
</ng-container>
+
<ng-container *ngIf="config.attribute === 'isRegex'">
- <span class="input-group-addon">
- <input type="checkbox"
- id="matcher-{{config.attribute}}-{{index}}"
- [checked]="matcher[config.attribute]"
- disabled
- readonly>
- </span>
+ <div class="input-group-append">
+ <div class="input-group-text">
+ <input type="checkbox"
+ id="matcher-{{config.attribute}}-{{index}}"
+ [checked]="matcher[config.attribute]"
+ disabled
+ readonly>
+ </div>
+ </div>
</ng-container>
</ng-container>
+
<!-- Matcher actions -->
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
id="matcher-edit-{{index}}"
i18n-tooltip
tooltip="Edit"
<i [ngClass]="[icons.edit]"></i>
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
id="matcher-delete-{{index}}"
i18n-tooltip
tooltip="Delete"
<div class="col-sm-12 col-lg-6">
<form #formDir="ngForm"
[formGroup]="form"
- class="form-horizontal"
+ class="form"
name="form"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 class="panel-title">
- <span i18n="@@formTitle">
- {{ action | titlecase }} {{ resource | upperFirst }}
- </span>
- <cd-helper *ngIf="edit"
- i18n>Editing a silence will expire the old silence and recreate it as a new silence</cd-helper>
- </h3>
+ <div class="card">
+ <div class="card-header">
+ <span i18n="@@formTitle">
+ {{ action | titlecase }} {{ resource | upperFirst }}
+ </span>
+ <cd-helper *ngIf="edit"
+ i18n>Editing a silence will expire the old silence and recreate it as a new silence</cd-helper>
</div>
<!-- Creator -->
- <div class="panel-body">
- <div [ngClass]="{'has-error': form.showError('createdBy', formDir)}"
- class="form-group">
- <label class="control-label col-sm-3"
+ <div class="card-body">
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="created-by">
<ng-container i18n>Creator</ng-container>
<span class="required"></span>
name="created-by"
type="text">
<span *ngIf="form.showError('createdBy', formDir, 'required')"
- class="help-block"
+ class="invalid-feedback"
i18n>This field is required!</span>
</div>
</div>
<!-- Comment -->
- <div [ngClass]="{'has-error': form.showError('comment', formDir)}"
- class="form-group">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="comment">
<ng-container i18n>Comment</ng-container>
<span class="required"></span>
type="text">
</textarea>
<span *ngIf="form.showError('comment', formDir, 'required')"
- class="help-block"
+ class="invalid-feedback"
i18n>This field is required!</span>
</div>
</div>
<!-- Start time -->
- <div [ngClass]="{'has-error': form.showError('startsAt', formDir)}"
- class="form-group">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="starts-at">
<ng-container i18n>Start time</ng-container>
<cd-helper i18n>If the start time lies in the past the creation time will be used</cd-helper>
id="starts-at"
name="starts-at">
<span *ngIf="form.showError('startsAt', formDir, 'required')"
- class="help-block"
+ class="invalid-feedback"
i18n>This field is required!</span>
</div>
</div>
<!-- Duration -->
- <div [ngClass]="{'has-error': form.showError('duration', formDir)}"
- class="form-group">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="duration">
<ng-container i18n>Duration</ng-container>
<span class="required"></span>
name="duration"
type="text">
<span *ngIf="form.showError('duration', formDir, 'required')"
- class="help-block"
+ class="invalid-feedback"
i18n>This field is required!</span>
</div>
</div>
<!-- End time -->
- <div [ngClass]="{'has-error': form.showError('endsAt', formDir)}"
- class="form-group">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="ends-at">
<ng-container i18n>End time</ng-container>
<span class="required"></span>
id="ends-at"
name="ends-at">
<span *ngIf="form.showError('endsAt', formDir, 'required')"
- class="help-block"
+ class="invalid-feedback"
i18n>This field is required!</span>
</div>
</div>
<!-- Matchers -->
<fieldset>
<legend i18n>Matchers<span class="required">*</span></legend>
- <div class="col-sm-offset-3 col-sm-9">
+
+ <div class="offset-sm-3 col-sm-9">
<h5 *ngIf="matchers.length === 0"
[ngClass]="{'text-warning': !formDir.submitted, 'text-danger': formDir.submitted}">
<strong i18n>A silence requires at least one matcher</strong>
<ng-container *ngTemplateOutlet="matcherTpl; context:{index: i, matcher: matcher}"></ng-container>
</span>
- <span class="form-control no-border">
- <button type="button"
- id="add-matcher"
- class="btn btn-sm btn-default btn-label pull-right"
- [ngClass]="{'btn-warning': formDir.submitted && matchers.length === 0 }"
- (click)="showMatcherModal()">
- <i [ngClass]="[icons.width, icons.add]"></i>
- <ng-container i18n>Add matcher</ng-container>
- </button>
- </span>
+ <div class="row">
+ <div class="col-12">
+ <button type="button"
+ id="add-matcher"
+ class="btn btn-light float-right my-3"
+ [ngClass]="{'btn-warning': formDir.submitted && matchers.length === 0 }"
+ (click)="showMatcherModal()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add matcher</ng-container>
+ </button>
+ </div>
+ </div>
</div>
+
<div *ngIf="matchers.length && matcherMatch"
- class="col-sm-offset-3 col-sm-9 {{matcherMatch.cssClass}}"
+ class="offset-sm-3 col-sm-9 {{matcherMatch.cssClass}}"
id="match-state">
- <span class="help-block {{matcherMatch.cssClass}}">
+ <span class="text-muted {{matcherMatch.cssClass}}">
{{ matcherMatch.status }}
</span>
</div>
</fieldset>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
<cd-submit-button (submitAction)="submit()"
[form]="formDir"
- id="submit"
- i18n="@@formTitle"
- type="button">
+ i18n="@@formTitle">
{{ action | titlecase }} {{ resource | upperFirst }}
</cd-submit-button>
<cd-back-button></cd-back-button>
selection = new CdTableSelection();
modalRef: BsModalRef;
customCss = {
- 'label label-danger': 'active',
- 'label label-warning': 'pending',
- 'label label-default': 'expired'
+ 'badge badge-danger': 'active',
+ 'badge badge-warning': 'pending',
+ 'badge badge-default': 'expired'
};
sorts: SortPropDir[] = [{ prop: 'endsAt', dir: SortDirection.desc }];
</button>
</div>
-<form class="form-horizontal"
+<form class="form"
#formDir="ngForm"
[formGroup]="form"
novalidate>
<div class="modal-body">
<!-- Name -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('name', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="name">
<ng-container i18n>Name</ng-container>
<span class="required"></span>
</div>
<!-- Value -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('value', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="value">
<ng-container i18n>Value</ng-container>
<span class="required"></span>
i18n>This field is required!</span>
</div>
<div *ngIf="form.getValue('value') && !form.getValue('isRegex') && matcherMatch"
- class="col-sm-offset-3 col-sm-9 {{matcherMatch.cssClass}}"
+ class="offset-sm-3 col-sm-9 {{matcherMatch.cssClass}}"
id="match-state">
- <span class="help-block {{matcherMatch.cssClass}}">
+ <span class="text-muted {{matcherMatch.cssClass}}">
{{matcherMatch.status}}
</span>
</div>
</div>
<!-- isRegex -->
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="input-group">
- <div class="checkbox checkbox-primary">
- <input id="is-regex"
- type="checkbox"
- formControlName="isRegex">
- <label for="is-regex"
- i18n>Use regular expression</label>
- </div>
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
+ <div class="custom-control custom-checkbox">
+ <input type="checkbox"
+ class="custom-control-input"
+ formControlName="isRegex"
+ name="is-regex"
+ id="is-regex">
+ <label for="is-regex"
+ class="custom-control-label"
+ i18n>Use regular expression</label>
</div>
</div>
</div>
</cd-back-button>
</div>
</form>
-
class="container-fluid">
<cd-info-group groupTitle="Status"
i18n-groupTitle
- class="row info-group"
*ngIf="healthData.health?.status
|| healthData.mon_status
|| healthData.osd_map
<cd-info-card cardTitle="Cluster Status"
i18n-cardTitle
- class="col-sm-6 col-md-4 col-lg-3"
- [contentClass]="healthData.health?.checks?.length > 0 ? 'content-highlight text-area-size-2' : 'content-highlight'"
+ class="cd-status-card"
+ contentClass="content-highlight"
*ngIf="healthData.health?.status">
<ng-container *ngIf="healthData.health?.checks?.length > 0">
<ng-template #healthChecks>
<cd-info-card cardTitle="Monitors"
i18n-cardTitle
link="/monitor"
- class="col-sm-6 col-md-4 col-lg-3"
+ class="cd-status-card"
contentClass="content-highlight"
*ngIf="healthData.mon_status">
{{ healthData.mon_status | monSummary }}
<cd-info-card cardTitle="OSDs"
i18n-cardTitle
link="/osd"
- class="col-sm-6 col-md-4 col-lg-3"
+ class="cd-status-card"
*ngIf="(healthData.osd_map | osdSummary) as transformedResult"
- [contentClass]="(transformedResult.length == 5 ? 'text-area-size-3' : 'text-area-size-2') + ' content-highlight'">
+ contentClass="content-highlight">
<span *ngFor="let result of transformedResult"
[ngClass]="result.class">
{{ result.content }}
<cd-info-card cardTitle="Manager Daemons"
i18n-cardTitle
- class="col-sm-6 col-md-4 col-lg-3"
- contentClass="content-highlight text-area-size-2"
+ class="cd-status-card"
+ contentClass="content-highlight"
*ngIf="healthData.mgr_map">
<span *ngFor="let result of (healthData.mgr_map | mgrSummary)"
[ngClass]="result.class"
<cd-info-card cardTitle="Hosts"
i18n-cardTitle
link="/hosts"
- class="col-sm-6 col-md-4 col-lg-3"
- contentClass="content-medium content-highlight"
+ class="cd-status-card"
+ contentClass="content-highlight"
*ngIf="healthData.hosts != null">
{{ healthData.hosts }} total
</cd-info-card>
<cd-info-card cardTitle="Object Gateways"
i18n-cardTitle
link="/rgw/daemon"
- class="col-sm-6 col-md-4 col-lg-3"
- contentClass="content-medium content-highlight"
+ class="cd-status-card"
+ contentClass="content-highlight"
*ngIf="enabledFeature.rgw && healthData.rgw != null">
{{ healthData.rgw }} total
</cd-info-card>
+
<cd-info-card cardTitle="Metadata Servers"
i18n-cardTitle
- class="col-sm-6 col-md-4 col-lg-3"
+ class="cd-status-card"
*ngIf="(enabledFeature.cephfs && healthData.fs_map | mdsSummary) as transformedResult"
[contentClass]="(transformedResult.length > 1 ? 'text-area-size-2' : '') + ' content-highlight'">
+ <!-- TODO: check text-area-size-2 -->
<span *ngFor="let result of transformedResult"
[ngClass]="result.class">
{{ result.content }}
<cd-info-card cardTitle="iSCSI Gateways"
i18n-cardTitle
link="/block/iscsi"
- class="col-sm-6 col-md-4 col-lg-3"
- contentClass="content-medium content-highlight"
+ class="cd-status-card"
+ contentClass="content-highlight"
*ngIf="enabledFeature.iscsi && healthData.iscsi_daemons != null">
{{ healthData.iscsi_daemons }} total
</cd-info-card>
<cd-info-group groupTitle="Performance"
i18n-groupTitle
- class="row info-group"
*ngIf="healthData.client_perf || healthData.scrub_status">
- <div class="cd-container-flex">
- <cd-info-card cardTitle="Client IOPS"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-medium content-highlight"
- *ngIf="healthData.client_perf">
- {{ (healthData.client_perf.read_op_per_sec + healthData.client_perf.write_op_per_sec) | round:1 }}
- </cd-info-card>
+ <cd-info-card cardTitle="Client IOPS"
+ i18n-cardTitle
+ class="cd-performance-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.client_perf">
+ {{ (healthData.client_perf.read_op_per_sec + healthData.client_perf.write_op_per_sec) | round:1 }}
+ </cd-info-card>
- <cd-info-card cardTitle="Client Throughput"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-medium content-highlight"
- *ngIf="healthData.client_perf">
- {{ ((healthData.client_perf.read_bytes_sec + healthData.client_perf.write_bytes_sec) | dimlessBinary) + '/s' }}
- </cd-info-card>
+ <cd-info-card cardTitle="Client Throughput"
+ i18n-cardTitle
+ class="cd-performance-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.client_perf">
+ {{ ((healthData.client_perf.read_bytes_sec + healthData.client_perf.write_bytes_sec) | dimlessBinary) + '/s' }}
+ </cd-info-card>
- <cd-info-card cardTitle="Client Read/Write"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- [contentClass]="isClientReadWriteChartShowable() ? 'content-chart': 'content-medium content-highlight'"
- *ngIf="healthData.client_perf">
- <cd-health-pie *ngIf="isClientReadWriteChartShowable()"
- [data]="healthData"
- (prepareFn)="prepareReadWriteRatio($event[0], $event[1])">
- </cd-health-pie>
- <span *ngIf="!isClientReadWriteChartShowable()">
- N/A
- </span>
- </cd-info-card>
+ <cd-info-card cardTitle="Client Read/Write"
+ i18n-cardTitle
+ class="cd-performance-card"
+ [contentClass]="isClientReadWriteChartShowable() ? 'content-chart': 'content-highlight'"
+ *ngIf="healthData.client_perf">
+ <cd-health-pie *ngIf="isClientReadWriteChartShowable()"
+ [data]="healthData"
+ (prepareFn)="prepareReadWriteRatio($event[0], $event[1])">
+ </cd-health-pie>
+ <span *ngIf="!isClientReadWriteChartShowable()">
+ N/A
+ </span>
+ </cd-info-card>
- <cd-info-card cardTitle="Recovery Throughput"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-medium content-highlight"
- *ngIf="healthData.client_perf">
- {{ (healthData.client_perf.recovering_bytes_per_sec | dimlessBinary) + '/s' }}
- </cd-info-card>
+ <cd-info-card cardTitle="Recovery Throughput"
+ i18n-cardTitle
+ class="cd-performance-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.client_perf">
+ {{ (healthData.client_perf.recovering_bytes_per_sec | dimlessBinary) + '/s' }}
+ </cd-info-card>
- <cd-info-card cardTitle="Scrub"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-medium content-highlight"
- *ngIf="healthData.scrub_status">
- {{ healthData.scrub_status }}
- </cd-info-card>
- </div>
+ <cd-info-card cardTitle="Scrub"
+ i18n-cardTitle
+ class="cd-performance-card"
+ contentClass="content-highlight"
+ *ngIf="healthData.scrub_status">
+ {{ healthData.scrub_status }}
+ </cd-info-card>
</cd-info-group>
<cd-info-group groupTitle="Capacity"
i18n-groupTitle
- class="row info-group"
*ngIf="healthData.pools
|| healthData.df
|| healthData.pg_info">
+ <cd-info-card cardTitle="Pools"
+ i18n-cardTitle
+ link="/pool"
+ class="cd-capacity-card order-md-1 order-lg-4 order-xl-1"
+ contentClass="content-highlight"
+ *ngIf="healthData.pools">
+ {{ healthData.pools.length }}
+ </cd-info-card>
- <div class="cd-container-flex">
- <cd-info-card cardTitle="Pools"
- i18n-cardTitle
- link="/pool"
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-medium content-highlight"
- *ngIf="healthData.pools">
- {{ healthData.pools.length }}
- </cd-info-card>
-
- <cd-info-card cardTitle="Raw Capacity"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-chart"
- *ngIf="healthData.df">
- <cd-health-pie [data]="healthData"
- [config]="rawCapacityChartConfig"
- [showLabelAsTooltip]="true"
- (prepareFn)="prepareRawUsage($event[0], $event[1])">
- </cd-health-pie>
- </cd-info-card>
+ <cd-info-card cardTitle="Raw Capacity"
+ i18n-cardTitle
+ class="cd-capacity-card order-md-3 order-lg-1 order-xl-2"
+ contentClass="content-chart"
+ *ngIf="healthData.df">
+ <cd-health-pie [data]="healthData"
+ [config]="rawCapacityChartConfig"
+ [isBytesData]="true"
+ (prepareFn)="prepareRawUsage($event[0], $event[1])">
+ </cd-health-pie>
+ </cd-info-card>
- <cd-info-card cardTitle="Objects"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-chart"
- *ngIf="healthData.pg_info?.object_stats?.num_objects != null">
- <cd-health-pie [data]="healthData"
- [config]="objectsChartConfig"
- (prepareFn)="prepareObjects($event[0], $event[1])">
- </cd-health-pie>
- </cd-info-card>
+ <cd-info-card cardTitle="Objects"
+ i18n-cardTitle
+ class="cd-capacity-card order-md-4 order-lg-2 order-xl-3"
+ contentClass="content-chart"
+ *ngIf="healthData.pg_info?.object_stats?.num_objects != null">
+ <cd-health-pie [data]="healthData"
+ [config]="objectsChartConfig"
+ (prepareFn)="prepareObjects($event[0], $event[1])">
+ </cd-health-pie>
+ </cd-info-card>
- <cd-info-card cardTitle="PGs per OSD"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-medium content-highlight"
- *ngIf="healthData.pg_info">
- {{ healthData.pg_info.pgs_per_osd | dimless }}
- </cd-info-card>
+ <cd-info-card cardTitle="PGs per OSD"
+ i18n-cardTitle
+ class="cd-capacity-card order-md-2 order-lg-5 order-xl-4"
+ contentClass="content-highlight"
+ *ngIf="healthData.pg_info">
+ {{ healthData.pg_info.pgs_per_osd | dimless }}
+ </cd-info-card>
- <cd-info-card cardTitle="PG Status"
- i18n-cardTitle
- class="cd-col-5"
- cardClass="card-medium"
- contentClass="content-chart"
- (click)="pgStatusTarget.toggle()"
- *ngIf="healthData.pg_info">
- <ng-template #pgStatus>
- <ng-container *ngTemplateOutlet="logsLink"></ng-container>
- <ul>
- <li *ngFor="let pgStatesText of healthData.pg_info.statuses | keyvalue">
- {{ pgStatesText.key }}: {{ pgStatesText.value }}
- </li>
- </ul>
- </ng-template>
- <div class="pg-status-popover-wrapper">
- <div [popover]="pgStatus"
- triggers=""
- #pgStatusTarget="bs-popover"
- placement="bottom">
- <cd-health-pie [data]="healthData"
- [config]="pgStatusChartConfig"
- (prepareFn)="preparePgStatus($event[0], $event[1])">
- </cd-health-pie>
- </div>
+ <cd-info-card cardTitle="PG Status"
+ i18n-cardTitle
+ class="cd-capacity-card order-md-5 order-lg-3 order-xl-5"
+ contentClass="content-chart"
+ (click)="pgStatusTarget.toggle()"
+ *ngIf="healthData.pg_info">
+ <ng-template #pgStatus>
+ <ng-container *ngTemplateOutlet="logsLink"></ng-container>
+ <ul>
+ <li *ngFor="let pgStatesText of healthData.pg_info.statuses | keyvalue">
+ {{ pgStatesText.key }}: {{ pgStatesText.value }}
+ </li>
+ </ul>
+ </ng-template>
+ <div class="pg-status-popover-wrapper">
+ <div [popover]="pgStatus"
+ triggers=""
+ #pgStatusTarget="bs-popover"
+ placement="bottom">
+ <cd-health-pie [data]="healthData"
+ [config]="pgStatusChartConfig"
+ (prepareFn)="preparePgStatus($event[0], $event[1])">
+ </cd-health-pie>
</div>
- </cd-info-card>
- </div>
+ </div>
+ </cd-info-card>
</cd-info-group>
<ng-template #logsLink>
-@import '../../../../defaults';
+@import 'styles';
cd-info-card {
padding: 0 0.5vw 0 0.5vw;
-}
-
-.cd-container-flex {
- margin: 0;
- padding: 0;
- display: -webkit-box;
- display: -webkit-flex;
- display: -ms-flexbox;
- display: flex;
- flex-flow: row wrap;
- justify-content: space-between;
-}
-
-.cd-col-5 {
- width: 20%;
-}
-
-@media (max-width: 1599px) {
- .cd-col-5 {
- width: 25%;
- }
-}
-
-@media (max-width: $screen-md-max) {
- .cd-col-5 {
- width: 33%;
- }
-}
-
-@media (max-width: $screen-sm-max) {
- .cd-col-5 {
- width: 50%;
- }
-}
-
-@media (max-width: $screen-xs-max) {
- cd-info-card {
- padding: 0;
- }
-
- .cd-col-5 {
- width: 100%;
- }
-}
-
-.info-group {
- margin: 0;
- padding: 0;
+ @extend .d-flex;
+ @extend .flex-column;
}
::ng-deep .pg-status-popover-wrapper {
.mgr-active-name:hover {
cursor: pointer;
}
+
+::ng-deep cd-info-card {
+ @extend .col-12;
+ @extend .col-sm-12;
+ @extend .col-md-6;
+ @extend .col-lg-4;
+
+ &.cd-status-card {
+ @extend .col-xl-3;
+ }
+
+ &.cd-performance-card,
+ &.cd-capacity-card {
+ @extend .col-xl;
+ }
+}
-@import '../../../../defaults';
+@import 'defaults';
.info-card-popover-cluster-status {
max-width: 23vw;
}
}
-@media (max-width: $screen-md-max) {
+@media (max-width: $screen-lg-max) {
.info-card-popover-cluster-status {
max-width: 31vw;
}
}
-@media (max-width: $screen-sm-max) {
+@media (max-width: $screen-md-max) {
.info-card-popover-cluster-status {
max-width: 46vw;
}
}
-@media (max-width: $screen-xs-max) {
+@media (max-width: $screen-sm-max) {
.info-card-popover-cluster-status {
max-width: 83vw;
}
-<div class="card"
+<div class="card mb-4"
[ngClass]="cardClass">
- <div class="card-title">
- <a *ngIf="link; else noLinkTitle"
- [routerLink]="link">{{ cardTitle }}</a>
- <ng-template #noLinkTitle>
- {{ cardTitle }}
- </ng-template>
- </div>
- <div class="card-body"
- [ngClass]="contentClass">
- <ng-content></ng-content>
+ <div class="card-body d-flex align-items-center justify-content-center">
+ <h5 class="card-title m-4">
+ <a *ngIf="link; else noLinkTitle"
+ [routerLink]="link">{{ cardTitle }}</a>
+
+ <ng-template #noLinkTitle>
+ {{ cardTitle }}
+ </ng-template>
+ </h5>
+
+ <div class="card-text text-center"
+ [ngClass]="contentClass">
+ <ng-content></ng-content>
+ </div>
</div>
</div>
-@import '../../../../defaults';
+@import 'styles';
-$card-height: 6vw;
-$card-medium-height: 12vw;
$card-font-min-width: 320px;
$card-font-max-width: 2048px;
$card-font-min-size: 12px;
$card-font-max-size: 21px;
-$logs-text-font-size: $card-font-min-size;
.card {
+ height: 100%;
+ @extend .pb-2;
border: 0.5px solid $color-info-card-border;
border-radius: 3px;
- background-color: $color-solid-white;
box-shadow: 0 1px 1px $color-shadow-gray;
- margin: 0 -10px 20px;
- padding: 0 20px;
- width: auto;
- height: auto;
- margin-left: auto;
- margin-right: auto;
- min-height: $card-height;
@include fluid-font-size(
$card-font-min-width,
$card-font-max-width,
$card-font-min-size,
$card-font-max-size
);
- position: relative;
-}
-.card-title {
- margin: 1.1vw 0;
- padding: 0;
-}
+ .card-body {
+ padding-top: 40px !important;
-.card-body {
- text-align: center;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%);
-}
+ .card-title {
+ position: absolute;
+ left: 0;
+ top: 0;
+ }
-.content-chart {
- margin-top: -0.7vw;
- position: unset;
- top: unset;
- left: unset;
- transform: unset;
+ .card-text {
+ @extend .pt-2;
+ }
+ }
}
.no-center {
transform: unset;
}
-.text-area-size-2 {
- margin-right: -50%;
- transform: translate(-50%, -20%);
-}
-
-.text-area-size-3 {
- margin-right: -50%;
- transform: translate(-50%, -40%);
-}
-
.content-highlight {
font-weight: bold;
}
-
-.card-medium {
- min-height: $card-medium-height;
-}
-
-.scroll {
- max-height: ($card-medium-height * 1.5);
- overflow-y: auto;
-}
-
-.text-monospace {
- font-size: $logs-text-font-size;
- font-family: monospace;
- text-align: left;
-}
-
-@media (max-width: 1599px) {
- .card {
- min-height: $card-height * 1.3;
- }
-
- .card-medium {
- min-height: $card-medium-height * 1.2;
- }
-}
-
-@media (max-width: $screen-md-max) {
- .card-medium {
- min-height: $card-medium-height * 1.5;
- }
-
- .content-chart {
- margin-top: -0.6vw;
- }
-}
-
-@media (max-width: $screen-sm-max) {
- .card {
- min-height: $card-height * 2;
- }
-
- .content-chart {
- margin-top: -0.3vw;
- }
-}
-
-@media (max-width: $screen-sm-max) and (min-width: $screen-sm-min) {
- .card-medium {
- min-height: $card-medium-height * 2.2;
- }
-}
-
-@media (max-width: 599px) {
- .card {
- min-height: $card-height * 3;
- }
-}
-
-@media (max-width: 319px) {
- .card {
- min-height: $card-height * 4;
- }
-}
const contentClass = 'my-css-content-class';
component.contentClass = contentClass;
fixture.detectChanges();
- const card = fixture.debugElement.nativeElement.querySelector(`.card-body.${contentClass}`);
+ const card = fixture.debugElement.nativeElement.querySelector(`.card-body .${contentClass}`);
expect(card).toBeTruthy();
});
-<div class="info-group-title">
- {{ groupTitle }}
+<div class="row">
+ <span class="info-group-title">{{ groupTitle }}</span>
+</div>
+<div class="row">
+ <ng-content></ng-content>
</div>
-<ng-content></ng-content>
-@import '../../../../defaults';
-
.info-group-title {
margin: 0 0 0.5vw 0.5vw;
- padding: 0;
font-size: 21px;
}
-<div class="form-group">
- <label class="col-sm-3 control-label"
+<div class="form-group row">
+ <label class="col-sm-3 col-form-label"
i18n>Clients</label>
<div class="col-sm-9"
[formGroup]="form"
#formDir="ngForm">
<span *ngIf="form.get('clients').value.length === 0"
- class="form-control no-border text-muted">
- <span class="text-muted"
+ class="no-border text-muted">
+ <span class="form-text text-muted"
i18n>Any client can access</span>
</span>
<ng-container formArrayName="clients">
<div *ngFor="let item of form.get('clients').value; let index = index; trackBy: trackByFn">
- <div class="panel panel-default"
+ <div class="card"
[formGroupName]="index">
- <div class="panel-heading">
- <h3 class="panel-title">{{ (index + 1) | ordinal }}
- <span class="pull-right clickable"
- (click)="removeClient(index)"
- tooltip="Remove">×</span>
- </h3>
+ <div class="card-header">
+ {{ (index + 1) | ordinal }}
+ <span class="float-right clickable"
+ (click)="removeClient(index)"
+ tooltip="Remove">×</span>
</div>
- <div class="panel-body">
+ <div class="card-body">
<!-- Addresses -->
- <div class="form-group"
- [ngClass]="{ 'has-error': showError(index, 'addresses', formDir) }">
+ <div class="form-group row"
+ [ngClass]="{ ':invalid': showError(index, 'addresses', formDir) }">
<label i18n
- class="col-sm-3 control-label"
+ class="col-sm-3 col-form-label"
for="addresses">Addresses</label>
<div class="col-sm-9">
<input type="text"
id="addresses"
formControlName="addresses"
placeholder="192.168.0.10, 192.168.1.0/8">
- <span class="help-block">
+ <span class="form-text text-muted">
<span *ngIf="showError(index, 'addresses', formDir, 'required')"
i18n>Required field</span>
</div>
<!-- Access Type-->
- <div class="form-group">
+ <div class="form-group row">
<label i18n
- class="col-sm-3 control-label"
+ class="col-sm-3 col-form-label"
for="access_type">Access Type</label>
<div class="col-sm-9">
<select class="form-control"
<option *ngFor="let item of nfsAccessType"
[value]="item.value">{{ item.value }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="getValue(index, 'access_type')">
{{ getAccessTypeHelp(index) }}
</span>
</div>
<!-- Squash -->
- <div class="form-group">
+ <div class="form-group row">
<label i18n
- class="col-sm-3 control-label"
+ class="col-sm-3 col-form-label"
for="squash">Squash</label>
<div class="col-sm-9">
<select class="form-control"
</div>
</ng-container>
- <span class="form-control no-border">
- <button class="btn btn-default btn-label pull-right"
- (click)="addClient()">
- <i [ngClass]="[icons.add, icons.width]"></i>
- <ng-container i18n>Add clients</ng-container>
- </button>
- </span>
- <hr>
+ <div class="row">
+ <div class="col-12">
+ <div class="float-right">
+ <button class="btn btn-light "
+ (click)="addClient()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>Add clients</ng-container>
+ </button>
+ </div>
+ </div>
+ </div>
</div>
</div>
<div class="col-sm-12 col-lg-6">
<form name="nfsForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="nfsForm"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 i18n="form title|Example: Create Pool@@formTitle"
- class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3>
- </div>
-
- <div class="panel-body">
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
<!-- cluster_id -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('cluster_id', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('cluster_id', formDir)}"
*ngIf="!isDefaultCluster">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="cluster_id">
<ng-container i18n>Cluster</ng-container>
<span class="required"></span>
<option *ngFor="let cluster of allClusters"
[value]="cluster">{{ cluster }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('cluster_id', formDir, 'required')"
i18n>Required field</span>
</div>
</div>
<!-- daemons -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('daemons', formDir)}">
- <label class="col-sm-3 control-label"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('daemons', formDir)}">
+ <label class="col-sm-3 col-form-label"
for="daemons">
<ng-container i18n>Daemons</ng-container>
</label>
<div class="col-sm-9">
<ng-container *ngFor="let daemon of nfsForm.getValue('daemons'); let i = index">
<div class="input-group cd-mb">
- <input class="form-control"
+ <input class="cd-form-control"
type="text"
[value]="daemon"
disabled />
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
type="button"
(click)="removeDaemon(i, daemon)">
- <i [ngClass]="[icons.destroy, icons.width]"
+ <i [ngClass]="[icons.destroy]"
aria-hidden="true"></i>
</button>
</span>
[options]="daemonsSelections"
[messages]="daemonsMessages"
(selection)="onDaemonSelection()"
- elemClass="btn btn-default pull-right">
- <i [ngClass]="[icons.add, icons.width]"></i>
+ elemClass="btn btn-light float-right">
+ <i [ngClass]="[icons.add]"></i>
<ng-container i18n>Add daemon</ng-container>
</cd-select>
</div>
<!-- FSAL -->
<div formGroupName="fsal">
<!-- Name -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('name', formDir)}">
- <label class="col-sm-3 control-label"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('name', formDir)}">
+ <label class="col-sm-3 col-form-label"
for="name">
<ng-container i18n>Storage Backend</ng-container>
<span class="required"></span>
<option *ngFor="let fsal of allFsals"
[value]="fsal.value">{{ fsal.descr }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('name', formDir, 'required')"
i18n>Required field</span>
</div>
</div>
<!-- RGW user -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('rgw_user_id', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('rgw_user_id', formDir)}"
*ngIf="nfsForm.getValue('name') === 'RGW'">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="rgw_user_id">
<ng-container i18n>Object Gateway User</ng-container>
<span class="required"></span>
<option *ngFor="let rgwUserId of allRgwUsers"
[value]="rgwUserId">{{ rgwUserId }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('rgw_user_id', formDir, 'required')"
i18n>Required field</span>
</div>
</div>
<!-- CephFS user_id -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('user_id', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('user_id', formDir)}"
*ngIf="nfsForm.getValue('name') === 'CEPH'">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="user_id">
<ng-container i18n>CephFS User ID</ng-container>
<span class="required"></span>
<option *ngFor="let client of allCephxClients"
[value]="client">{{ client }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('user_id', formDir, 'required')"
i18n>Required field</span>
</div>
</div>
<!-- CephFS fs_name -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('fs_name', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('fs_name', formDir)}"
*ngIf="nfsForm.getValue('name') === 'CEPH'">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="fs_name">
<ng-container i18n>CephFS Name</ng-container>
<span class="required"></span>
<option *ngFor="let filesystem of allFsNames"
[value]="filesystem.name">{{ filesystem.name }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('fs_name', formDir, 'required')"
i18n>Required field</span>
</div>
</div>
<!-- Secutiry Label -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('security_label', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('security_label', formDir)}"
*ngIf="nfsForm.getValue('name') === 'CEPH'">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="security_label">
<ng-container i18n>Security Label</ng-container>
<span class="required"
id="sec_label_xattr"
formControlName="sec_label_xattr">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('sec_label_xattr', formDir, 'required')"
i18n>Required field</span>
</div>
</div>
<!-- Path -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('path', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('path', formDir)}"
*ngIf="nfsForm.getValue('name') === 'CEPH'">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="path">
<ng-container i18n>CephFS Path</ng-container>
<span class="required"></span>
[typeahead]="pathDataSource"
(typeaheadOnSelect)="pathChangeHandler()"
(blur)="pathChangeHandler()">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('path', formDir, 'required')"
i18n>Required field</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('path', formDir, 'pattern')"
i18n>Path need to start with a '/' and can be followed by a word</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="isNewDirectory && !nfsForm.showError('path', formDir)"
i18n>New directory will be created</span>
</div>
</div>
<!-- Bucket -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('path', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('path', formDir)}"
*ngIf="nfsForm.getValue('name') === 'RGW'">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="path">
<ng-container i18n>Path</ng-container>
<span class="required"></span>
(typeaheadOnSelect)="bucketChangeHandler()"
(blur)="bucketChangeHandler()">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('path', formDir, 'required')"
i18n>Required field</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('path', formDir, 'pattern')"
i18n>Path can only be a single '/' or a word</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="isNewBucket && !nfsForm.showError('path', formDir)"
i18n>New bucket will be created</span>
</div>
</div>
<!-- NFS Protocol -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('protocolNfsv3', formDir) || nfsForm.showError('protocolNfsv4', formDir)}">
- <label class="col-sm-3 control-label"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('protocolNfsv3', formDir) || nfsForm.showError('protocolNfsv4', formDir)}">
+ <label class="col-sm-3 col-form-label"
for="protocols">
<ng-container i18n>NFS Protocol</ng-container>
<span class="required"></span>
<label i18n
for="protocolNfsv4">NFSv4</label>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('protocolNfsv3', formDir, 'required') ||
nfsForm.showError('protocolNfsv4', formDir, 'required')"
i18n>Required field</span>
</div>
<!-- Tag -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="nfsForm.getValue('protocolNfsv3')">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="tag">
<ng-container i18n>NFS Tag</ng-container>
<cd-helper>
</div>
<!-- Pseudo -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('pseudo', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('pseudo', formDir)}"
*ngIf="nfsForm.getValue('protocolNfsv4')">
- <label class="col-sm-3 control-label"
+ <label class="col-sm-3 col-form-label"
for="pseudo">
<ng-container i18n>Pseudo</ng-container>
<span class="required"></span>
name="pseudo"
id="pseudo"
formControlName="pseudo">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('pseudo', formDir, 'required')"
i18n>Required field</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('pseudo', formDir, 'pattern')"
i18n>Pseudo needs to start with a '/' and can't contain any of the following: >, <, |, &, ( or ).</span>
</div>
</div>
<!-- Access Type -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('access_type', formDir)}">
- <label class="col-sm-3 control-label"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('access_type', formDir)}">
+ <label class="col-sm-3 col-form-label"
for="access_type">
<ng-container i18n>Access Type</ng-container>
<span class="required"></span>
<option *ngFor="let accessType of nfsAccessType"
[value]="accessType.value">{{ accessType.value }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.getValue('access_type')">
{{ getAccessTypeHelp(nfsForm.getValue('access_type')) }}
</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('access_type', formDir, 'required')"
i18n>Required field</span>
</div>
</div>
<!-- Squash -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('squash', formDir)}">
- <label class="col-sm-3 control-label"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('squash', formDir)}">
+ <label class="col-sm-3 col-form-label"
for="squash">
<ng-container i18n>Squash</ng-container>
<span class="required"></span>
[value]="squash">{{ squash }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('squash', formDir,'required')"
i18n>Required field</span>
</div>
</div>
<!-- Transport Protocol -->
- <div class="form-group"
- [ngClass]="{'has-error': nfsForm.showError('transportUDP', formDir) || nfsForm.showError('transportTCP', formDir)}">
- <label class="col-sm-3 control-label"
+ <div class="form-group row"
+ [ngClass]="{':invalid': nfsForm.showError('transportUDP', formDir) || nfsForm.showError('transportTCP', formDir)}">
+ <label class="col-sm-3 col-form-label"
for="transports">
<ng-container i18n>Transport Protocol</ng-container>
<span class="required"></span>
<label for="transportTCP"
i18n>TCP</label>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="nfsForm.showError('transportUDP', formDir, 'required') ||
nfsForm.showError('transportTCP', formDir, 'required')"
i18n>Required field</span>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
<cd-submit-button
- [form]="formDir"
(submitAction)="submitAction()"
i18n="form action button|Example: Create Pool@@formActionButton"
- type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ [form]="formDir">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
<div class="modal-header">
<h4 i18n="form title|Example: Create Pool@@formTitle"
- class="modal-title pull-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+ class="modal-title float-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+
<button type="button"
- class="close pull-right"
+ class="close float-right"
aria-label="Close"
(click)="bsModalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
-<form class="form-horizontal"
- #frm="ngForm"
+<form #frm="ngForm"
[formGroup]="form"
novalidate>
<div class="modal-body">
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('name', frm)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('name', frm)}">
<label for="name"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Name</ng-container>
<span class="required"></span>
</label>
placeholder="Name..."
formControlName="name"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('name', frm, 'required')"
i18n>This field is required!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('name', frm, 'pattern')"
i18n>The name can only consist of alphanumeric characters, dashes and underscores.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('name', frm, 'uniqueName')"
i18n>The chosen erasure code profile name is already in use.</span>
</div>
</div>
- <div class="form-group">
+ <div class="form-group row">
<label for="plugin"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Plugin</ng-container>
<span class="required"></span>
<cd-helper [html]="tooltips.plugins[plugin].description">
{{ plugin }}
</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('name', frm, 'required')"
i18n>This field is required!</span>
</div>
</div>
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('k', frm)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('k', frm)}">
<label for="k"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Data chunks (k)</ng-container>
<span class="required"
*ngIf="requiredControls.includes('k')"></span>
ng-model="$ctrl.erasureCodeProfile.k"
placeholder="Data chunks..."
formControlName="k">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('k', frm, 'required')"
i18n>This field is required!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('k', frm, 'min')"
i18n>Must be equal to or greater than 2.</span>
</div>
</div>
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('m', frm)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('m', frm)}">
<label for="m"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Coding chunks (m)</ng-container>
<span class="required"
*ngIf="requiredControls.includes('m')"></span>
class="form-control"
placeholder="Coding chunks..."
formControlName="m">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('m', frm, 'required')"
i18n>This field is required!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('m', frm, 'min')"
i18n>Must be equal to or greater than 1.</span>
</div>
</div>
- <div class="form-group"
+ <div class="form-group row"
*ngIf="plugin === 'shec'"
- [ngClass]="{'has-error': form.showError('c', frm)}">
+ [ngClass]="{':invalid': form.showError('c', frm)}">
<label for="c"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Durability estimator (c)</ng-container>
<cd-helper [html]="tooltips.plugins.shec.c">
</cd-helper>
class="form-control"
placeholder="Coding chunks..."
formControlName="c">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('c', frm, 'min')"
i18n>Must be equal to or greater than 1.</span>
</div>
</div>
- <div class="form-group"
+ <div class="form-group row"
*ngIf="plugin === PLUGIN.LRC"
- [ngClass]="{'has-error': form.showError('l', frm)}">
+ [ngClass]="{':invalid': form.showError('l', frm)}">
<label for="l"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Locality (l)</ng-container>
<span class="required"></span>
<cd-helper [html]="tooltips.plugins.lrc.l">
class="form-control"
placeholder="Coding chunks..."
formControlName="l">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('l', frm, 'required')"
i18n>This field is required!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('l', frm, 'min')"
i18n>Must be equal to or greater than 1.</span>
</div>
</div>
- <div class="form-group">
+ <div class="form-group row">
<label for="crushFailureDomain"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Crush failure domain</ng-container>
<cd-helper [html]="tooltips.crushFailureDomain">
</cd-helper>
</div>
</div>
- <div class="form-group"
+ <div class="form-group row"
*ngIf="plugin === PLUGIN.LRC">
<label for="crushLocality"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Crush Locality</ng-container>
<cd-helper [html]="tooltips.plugins.lrc.crushLocality">
</cd-helper>
</div>
</div>
- <div class="form-group"
+ <div class="form-group row"
*ngIf="[PLUGIN.JERASURE, PLUGIN.ISA].includes(plugin)">
<label for="technique"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Technique</ng-container>
<cd-helper [html]="tooltips.plugins[plugin].technique">
</cd-helper>
</div>
</div>
- <div class="form-group"
+ <div class="form-group row"
*ngIf="plugin === PLUGIN.JERASURE"
- [ngClass]="{'has-error': form.showError('packetSize', frm)}">
+ [ngClass]="{':invalid': form.showError('packetSize', frm)}">
<label for="packetSize"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Packetsize</ng-container>
<cd-helper [html]="tooltips.plugins.jerasure.packetSize">
</cd-helper>
class="form-control"
placeholder="Packetsize..."
formControlName="packetSize">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('packetSize', frm, 'min')"
i18n>Must be equal to or greater than 1.</span>
</div>
</div>
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('crushRoot', frm)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('crushRoot', frm)}">
<label for="crushRoot"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Crush root</ng-container>
<cd-helper [html]="tooltips.crushRoot">
</cd-helper>
</div>
</div>
- <div class="form-group">
+ <div class="form-group row">
<label for="crushDeviceClass"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Crush device class</ng-container>
<cd-helper [html]="tooltips.crushDeviceClass">
</cd-helper>
</div>
</div>
- <div class="form-group">
+ <div class="form-group row">
<label for="directory"
- class="control-label col-sm-3">
+ class="col-form-label col-sm-3">
<ng-container i18n>Directory</ng-container>
<cd-helper [html]="tooltips.directory">
</cd-helper>
</div>
<div class="modal-footer">
- <cd-submit-button
- (submitAction)="onSubmit()"
- i18n="form action button|Example: Create Pool@@formActionButton"
- [form]="frm">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="onSubmit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="frm">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button [back]="bsModalRef.hide"></cd-back-button>
</div>
</form>
<div class="col-sm-12 col-lg-6">
<h1 *ngIf="!(info && ecProfiles)"
class="jumbotron">
- <i [ngClass]="[icons.spinner, icons.pulse, icons.large]" class="text-primary"></i>
+ <i [ngClass]="[icons.spinner, icons.pulse, icons.large]"
+ class="text-primary"></i>
<ng-container i18n>Loading...</ng-container>
</h1>
<form name="form"
*ngIf="info && ecProfiles"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="form"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 i18n="form title|Example: Create Pool@@formTitle"
- class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3>
- </div>
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
- <div class="panel-body">
+ <div class="card-body">
<!-- Name -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('name', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('name', formDir)}">
+ <label class="col-form-label col-sm-3"
for="name">
<ng-container i18n>Name</ng-container>
<span class="required"></span>
i18n-placeholder
formControlName="name"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('name', formDir, 'required')"
i18n>This field is required!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('name', formDir, 'uniqueName')"
i18n>The chosen Ceph pool name is already in use.</span>
</div>
</div>
<!-- Pool type selection -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('poolType', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('poolType', formDir)}">
+ <label class="col-form-label col-sm-3"
for="poolType">
<ng-container i18n>Pool type</ng-container>
<span class="required"></span>
{{ poolType }}
</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('poolType', formDir, 'required')"
i18n>This field is required!</span>
</div>
<div *ngIf="form.getValue('poolType')">
<!-- Pg number -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('pgNum', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('pgNum', formDir)}">
+ <label class="col-form-label col-sm-3"
for="pgNum">
<ng-container i18n>Placement groups</ng-container>
<span class="required"></span>
(focus)="externalPgChange = false"
(blur)="alignPgs()"
required>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('pgNum', formDir, 'required')"
i18n>This field is required!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('pgNum', formDir, 'min')"
i18n>At least one placement group is needed!</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('pgNum', formDir, '34')"
i18n>Your cluster can't handle this many PGs. Please recalculate the PG amount needed.</span>
- <span class="help-block">
+ <span class="form-text text-muted">
<a i18n
target="_blank"
href="http://ceph.com/pgcalc">Calculation help</a>
</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="externalPgChange"
i18n>The current PGs settings were calculated for you, you
should make sure the values suit your needs before submit.</span>
</div>
<!-- Crush ruleset selection -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('crushRule', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('crushRule', formDir)}"
*ngIf="form.getValue('poolType') && current.rules.length > 0">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="crushRule"
i18n>Crush ruleset</label>
<div class="col-sm-9">
{{ rule.rule_name }}
</option>
</select>
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
[ngClass]="{'active': data.crushInfo}"
id="crush-info-button"
type="button"
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
id="crush-info-block"
*ngIf="data.crushInfo && form.getValue('crushRule')">
<tabset>
- <tab i18n-heading heading="Crush rule" class="crush-rule-info">
+ <tab i18n-heading
+ heading="Crush rule"
+ class="crush-rule-info">
<cd-table-key-value [renderObjects]="true"
[data]="form.getValue('crushRule')"
[autoReload]="false">
</cd-table-key-value>
</tab>
- <tab i18n-heading heading="Crush steps" class="crush-rule-steps">
+ <tab i18n-heading
+ heading="Crush steps"
+ class="crush-rule-steps">
<ol>
<li *ngFor="let step of form.get('crushRule').value.steps">
{{ describeCrushStep(step) }}
</tab>
</tabset>
</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('crushRule', formDir, 'tooFewOsds')"
i18n>The rule can't be used in the current cluster as it has
to few OSDs to meet the minimum required OSD by this rule.</span>
</div>
<!-- Replica Size -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('size', formDir)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('size', formDir)}"
*ngIf="form.getValue('poolType') === 'replicated'">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="size">
<ng-container i18n>Replicated size</ng-container>
<span class="required"></span>
name="size"
type="number"
formControlName="size">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('size', formDir)">
<ul class="list-inline">
<li i18n>Minimum: {{ getMinSize() }}</li>
<li i18n>Maximum: {{ getMaxSize() }}</li>
</ul>
</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('size', formDir)"
i18n>The size specified is out of range. A value from
- {{ getMinSize() }} to {{ getMaxSize() }} is valid.</span>
+ {{ getMinSize() }} to {{ getMaxSize() }} is valid.</span>
</div>
</div>
<!-- Erasure Profile select -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="form.getValue('poolType') === 'erasure'">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="erasureProfile">Erasure code profile</label>
<div class="col-sm-9">
<div class="input-group">
{{ ecp.name }}
</option>
</select>
- <span class="input-group-btn">
- <button class="btn btn-default"
+ <span class="input-group-append">
+ <button class="btn btn-light"
[ngClass]="{'active': data.erasureInfo}"
id="ecp-info-button"
type="button"
<i [ngClass]="[icons.questionCircle]"
aria-hidden="true"></i>
</button>
- <button class="btn btn-default"
+ <button class="btn btn-light"
type="button"
[disabled]="editing"
(click)="addErasureCodeProfile()">
<i [ngClass]="[icons.add]"
aria-hidden="true"></i>
</button>
- <button class="btn btn-default"
+ <button class="btn btn-light"
type="button"
(click)="deleteErasureCodeProfile()"
[disabled]="editing || ecProfiles.length < 1">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
id="ecp-info-block"
*ngIf="data.erasureInfo && form.getValue('erasureProfile')">
<cd-table-key-value [renderObjects]="true"
</div>
<!-- Flags -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="info.is_all_bluestore && form.getValue('poolType') === 'erasure'">
<label i18n
- class="control-label col-sm-3">Flags</label>
+ class="col-form-label col-sm-3">Flags</label>
<div class="col-sm-9">
- <div class="input-group">
- <div class="checkbox checkbox-primary">
- <input id="ec-overwrites"
- type="checkbox"
- formControlName="ecOverwrites">
- <label for="ec-overwrites"
- i18n>EC Overwrites</label>
- </div>
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="ec-overwrites"
+ type="checkbox"
+ formControlName="ecOverwrites">
+ <label class="form-check-label"
+ for="ec-overwrites"
+ i18n>EC Overwrites</label>
</div>
</div>
</div>
</div>
<!-- Applications -->
- <div class="form-group">
+ <div class="form-group row">
<label i18n
- class="col-sm-3 control-label"
+ class="col-sm-3 col-form-label"
for="applications">Applications</label>
<div class="col-sm-9">
- <span class="form-control no-border full-height">
- <cd-select-badges id="applications"
- [customBadges]="true"
- [customBadgeValidators]="data.applications.validators"
- [messages]="data.applications.messages"
- [data]="data.applications.selected"
- [options]="data.applications.available"
- [selectionLimit]="4"
- (selection)="appSelection()">
- </cd-select-badges>
- </span>
+ <cd-select-badges id="applications"
+ [customBadges]="true"
+ [customBadgeValidators]="data.applications.validators"
+ [messages]="data.applications.messages"
+ [data]="data.applications.selected"
+ [options]="data.applications.available"
+ [selectionLimit]="4"
+ (selection)="appSelection()">
+ </cd-select-badges>
</div>
</div>
<legend i18n>Compression</legend>
<!-- Compression Mode -->
- <div class="form-group">
+ <div class="form-group row">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="mode">Mode</label>
<div class="col-sm-9">
<select class="form-control"
</div>
<div *ngIf="hasCompressionEnabled()">
<!-- Compression algorithm selection -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('algorithm', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('algorithm', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="algorithm">Algorithm</label>
<div class="col-sm-9">
<select class="form-control"
</div>
<!-- Compression min blob size -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('minBlobSize', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('minBlobSize', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="minBlobSize">Minimum blob size</label>
<div class="col-sm-9">
<input id="minBlobSize"
placeholder="e.g., 128KiB"
defaultUnit="KiB"
cdDimlessBinary>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('minBlobSize', formDir, 'min')"
i18n>Value should be greater than 0</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('minBlobSize', formDir, 'maximum')"
i18n>Value should be less than the maximum blob size</span>
</div>
</div>
<!-- Compression max blob size -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('maxBlobSize', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('maxBlobSize', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="maxBlobSize">Maximum blob size</label>
<div class="col-sm-9">
<input id="maxBlobSize"
placeholder="e.g., 512KiB"
defaultUnit="KiB"
cdDimlessBinary>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('maxBlobSize', formDir, 'min')"
i18n>Value should be greater than 0</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('maxBlobSize', formDir, 'minimum')"
i18n>Value should be greater than the minimum blob size</span>
</div>
</div>
<!-- Compression ratio -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('ratio', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': form.showError('ratio', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="ratio">Ratio</label>
<div class="col-sm-9">
<input id="ratio"
class="form-control"
i18n-placeholder
placeholder="Compression ratio">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="form.showError('ratio', formDir, 'min') || form.showError('ratio', formDir, 'max')"
i18n>Value should be between 0.0 and 1.0</span>
</div>
<legend i18n>Quotas</legend>
<!-- Max Bytes -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('max_bytes', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="max_bytes">
<ng-container i18n>Max bytes</ng-container>
<cd-helper>
</div>
<!-- Max Objects -->
- <div class="form-group"
- [ngClass]="{'has-error': form.showError('max_objects', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="max_objects">
<ng-container i18n>Max objects</ng-container>
<cd-helper>
name="max_objects"
type="number"
formControlName="max_objects">
- <span class="help-block"
+ <span class="invalid-feedback"
*ngIf="form.showError('max_objects', formDir, 'min')"
i18n>The value should be greater or equal to 0</span>
</div>
</cd-rbd-configuration-form>
</div>
- <div class="form-group has-error">
- <div class="col-sm-offset-3 col-sm-9"
+ <div class="form-group :invalid">
+ <div class="offset-sm-3 col-sm-9"
*ngIf="form.hasError('rbdPool')">
<br>
- <span class="help-block"
+ <span class="form-text text-muted"
i18n>It's not possible to create an RBD pool with '/' in the name.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
i18n>Please change the name or remove 'rbd' from the applications list.</span>
</div>
</div>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
- <cd-submit-button
- [form]="formDir"
- type="button"
- i18n="form action button|Example: Create Pool@@formActionButton"
- (submitAction)="submit()">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button [form]="formDir"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ (submitAction)="submit()">{{ action | titlecase }} {{ resource | upperFirst }}
+ </cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
-@import '../../../../defaults';
+@import 'defaults';
::ng-deep .pg-clean {
color: $color-bright-green;
<tabset *ngIf="selection.hasSingleSelection">
- <tab i18n-heading heading="Details">
+ <tab i18n-heading
+ heading="Details">
<div *ngIf="bucket">
<table class="table table-striped table-bordered">
<tbody>
<tr>
<td i18n
- class="bold col-sm-1">Name</td>
- <td class="col-sm-3">{{ bucket.bid }}</td>
+ class="bold w-25">Name</td>
+ <td class="w-75">{{ bucket.bid }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">ID</td>
+ class="bold">ID</td>
<td>{{ bucket.id }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Owner</td>
+ class="bold">Owner</td>
<td>{{ bucket.owner }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Index type</td>
+ class="bold">Index type</td>
<td>{{ bucket.index_type }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Placement rule</td>
+ class="bold">Placement rule</td>
<td>{{ bucket.placement_rule }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Marker</td>
+ class="bold">Marker</td>
<td>{{ bucket.marker }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Maximum marker</td>
+ class="bold">Maximum marker</td>
<td>{{ bucket.max_marker }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Version</td>
+ class="bold">Version</td>
<td>{{ bucket.ver }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Master version</td>
+ class="bold">Master version</td>
<td>{{ bucket.master_ver }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Modification time</td>
+ class="bold">Modification time</td>
<td>{{ bucket.mtime | cdDate }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Zonegroup</td>
+ class="bold">Zonegroup</td>
<td>{{ bucket.zonegroup }}</td>
</tr>
</tbody>
<tbody>
<tr>
<td i18n
- class="bold col-sm-1">Enabled</td>
- <td class="col-sm-3">{{ bucket.bucket_quota.enabled | booleanText }}</td>
+ class="bold w-25">Enabled</td>
+ <td class="w-75">{{ bucket.bucket_quota.enabled | booleanText }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Maximum size</td>
+ class="bold">Maximum size</td>
<td *ngIf="bucket.bucket_quota.max_size <= -1"
- i18n
- class="col-sm-3">Unlimited</td>
- <td *ngIf="bucket.bucket_quota.max_size > -1"
- class="col-sm-3">
+ i18n>Unlimited</td>
+ <td *ngIf="bucket.bucket_quota.max_size > -1">
{{ bucket.bucket_quota.max_size | dimless }}
</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Maximum objects</td>
+ class="bold">Maximum objects</td>
<td *ngIf="bucket.bucket_quota.max_objects <= -1"
- i18n
- class="col-sm-3">Unlimited</td>
- <td *ngIf="bucket.bucket_quota.max_objects > -1"
- class="col-sm-3">
+ i18n>Unlimited</td>
+ <td *ngIf="bucket.bucket_quota.max_objects > -1">
{{ bucket.bucket_quota.max_objects }}
</td>
</tr>
<div class="col-sm-12 col-lg-6"
*ngIf="!loading && !error">
<form name="bucketForm"
- class="form-horizontal"
#frm="ngForm"
[formGroup]="bucketForm"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 i18n="form title|Example: Create Pool@@formTitle"
- class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3>
- </div>
- <div class="panel-body">
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
<!-- Id -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="editing">
<label i18n
- class="col-sm-3 control-label"
+ class="col-sm-3 col-form-label"
for="id">Id</label>
<div class="col-sm-9">
<input id="id"
</div>
<!-- Name -->
- <div class="form-group"
- [ngClass]="{'has-error': bucketForm.showError('bid', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': bucketForm.showError('bid', frm)}">
+ <label class="col-form-label col-sm-3"
for="bid">
<ng-container i18n>Name</ng-container>
<span class="required"
formControlName="bid"
[readonly]="editing"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="bucketForm.showError('bid', frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="bucketForm.showError('bid', frm, 'bucketNameInvalid')"
i18n>The value is not valid.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="bucketForm.showError('bid', frm, 'bucketNameExists')"
i18n>The chosen name is already in use.</span>
</div>
</div>
<!-- Owner -->
- <div class="form-group"
- [ngClass]="{'has-error': bucketForm.showError('owner', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': bucketForm.showError('owner', frm)}">
+ <label class="col-form-label col-sm-3"
for="owner">
<ng-container i18n>Owner</ng-container>
<span class="required"></span>
<option *ngFor="let owner of owners"
[value]="owner">{{ owner }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="bucketForm.showError('owner', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
- <cd-submit-button
- (submitAction)="submit()" [form]="bucketForm"
- i18n="form action button|Example: Create Pool@@formActionButton"
- type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="submit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="bucketForm">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
<div class="modal-header">
<h4 i18n="form title|Example: Create Pool@@formTitle"
- class="modal-title pull-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+ class="modal-title float-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+
<button type="button"
- class="close pull-right"
+ class="close float-right"
aria-label="Close"
(click)="bsModalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
-<form class="form-horizontal"
- #frm="ngForm"
+<form #frm="ngForm"
[formGroup]="formGroup"
novalidate>
<div class="modal-body">
<!-- Type -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('type', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('type', frm)}">
+ <label class="col-form-label col-sm-3"
for="type">
<ng-container i18n>Type</ng-container>
<span class="required"
<option *ngFor="let type of types"
[value]="type">{{ type }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('type', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Permission -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('perm', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('perm', frm)}">
+ <label class="col-form-label col-sm-3"
for="perm">
<ng-container i18n>Permission</ng-container>
<span class="required"></span>
{{ perm }}
</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('perm', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
<div class="modal-footer">
- <cd-submit-button
- (submitAction)="onSubmit()"
- i18n="form action button|Example: Create Pool@@formActionButton"
- [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="onSubmit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button [back]="bsModalRef.hide"></cd-back-button>
</div>
</form>
<tbody>
<tr>
<td i18n
- class="bold col-sm-1">Username</td>
- <td class="col-sm-3">{{ user.uid }}</td>
+ class="bold w-25">Username</td>
+ <td class="w-75">{{ user.uid }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Full name</td>
- <td class="col-sm-3">{{ user.display_name }}</td>
+ class="bold">Full name</td>
+ <td>{{ user.display_name }}</td>
</tr>
<tr *ngIf="user.email.length">
<td i18n
- class="bold col-sm-1">Email address</td>
- <td class="col-sm-3">{{ user.email }}</td>
+ class="bold">Email address</td>
+ <td>{{ user.email }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Suspended</td>
- <td class="col-sm-3">{{ user.suspended | booleanText }}</td>
+ class="bold">Suspended</td>
+ <td>{{ user.suspended | booleanText }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">System</td>
- <td class="col-sm-3">{{ user.system | booleanText }}</td>
+ class="bold">System</td>
+ <td>{{ user.system | booleanText }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Maximum buckets</td>
- <td class="col-sm-3">{{ user.max_buckets }}</td>
+ class="bold">Maximum buckets</td>
+ <td>{{ user.max_buckets }}</td>
</tr>
<tr *ngIf="user.subusers && user.subusers.length">
<td i18n
- class="bold col-sm-1">Subusers</td>
- <td class="col-sm-3">
+ class="bold">Subusers</td>
+ <td>
<div *ngFor="let subuser of user.subusers">
{{ subuser.id }} ({{ subuser.permissions }})
</div>
</tr>
<tr *ngIf="user.caps && user.caps.length">
<td i18n
- class="bold col-sm-1">Capabilities</td>
- <td class="col-sm-3">
+ class="bold">Capabilities</td>
+ <td>
<div *ngFor="let cap of user.caps">
{{ cap.type }} ({{ cap.perm }})
</div>
<tbody>
<tr>
<td i18n
- class="bold col-sm-1">Enabled</td>
- <td class="col-sm-3">{{ user.user_quota.enabled | booleanText }}</td>
+ class="bold w-25">Enabled</td>
+ <td class="w-75">{{ user.user_quota.enabled | booleanText }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Maximum size</td>
- <td *ngIf="!user.user_quota.enabled"
- class="col-sm-3">-</td>
+ class="bold">Maximum size</td>
+ <td *ngIf="!user.user_quota.enabled">-</td>
<td *ngIf="user.user_quota.enabled && user.user_quota.max_size <= -1"
- i18n
- class="col-sm-3">Unlimited</td>
- <td *ngIf="user.user_quota.enabled && user.user_quota.max_size > -1"
- class="col-sm-3">
+ i18n>Unlimited</td>
+ <td *ngIf="user.user_quota.enabled && user.user_quota.max_size > -1">
{{ user.user_quota.max_size | dimlessBinary }}
</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Maximum objects</td>
- <td *ngIf="!user.user_quota.enabled"
- class="col-sm-3">-</td>
+ class="bold">Maximum objects</td>
+ <td *ngIf="!user.user_quota.enabled">-</td>
<td *ngIf="user.user_quota.enabled && user.user_quota.max_objects <= -1"
- i18n
- class="col-sm-3">Unlimited</td>
- <td *ngIf="user.user_quota.enabled && user.user_quota.max_objects > -1"
- class="col-sm-3">
+ i18n>Unlimited</td>
+ <td *ngIf="user.user_quota.enabled && user.user_quota.max_objects > -1">
{{ user.user_quota.max_objects }}
</td>
</tr>
<tbody>
<tr>
<td i18n
- class="bold col-sm-1">Enabled</td>
- <td class="col-sm-3">{{ user.bucket_quota.enabled | booleanText }}</td>
+ class="bold w-25">Enabled</td>
+ <td class="w-75">{{ user.bucket_quota.enabled | booleanText }}</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Maximum size</td>
- <td *ngIf="!user.bucket_quota.enabled"
- class="col-sm-3">-</td>
+ class="bold">Maximum size</td>
+ <td *ngIf="!user.bucket_quota.enabled">-</td>
<td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_size <= -1"
- i18n
- class="col-sm-3">Unlimited</td>
- <td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_size > -1"
- class="col-sm-3">
+ i18n>Unlimited</td>
+ <td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_size > -1">
{{ user.bucket_quota.max_size | dimlessBinary }}
</td>
</tr>
<tr>
<td i18n
- class="bold col-sm-1">Maximum objects</td>
- <td *ngIf="!user.bucket_quota.enabled"
- class="col-sm-3">-</td>
+ class="bold">Maximum objects</td>
+ <td *ngIf="!user.bucket_quota.enabled">-</td>
<td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_objects <= -1"
- i18n
- class="col-sm-3">Unlimited</td>
- <td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_objects > -1"
- class="col-sm-3">
+ i18n>Unlimited</td>
+ <td *ngIf="user.bucket_quota.enabled && user.bucket_quota.max_objects > -1">
{{ user.bucket_quota.max_objects }}
</td>
</tr>
<div class="btn-group"
dropdown>
<button type="button"
- class="btn btn-sm btn-primary"
+ class="btn btn-secondary"
[disabled]="!keysSelection.hasSingleSelection"
(click)="showKeyModal()">
<i [ngClass]="[icons.show]"></i>
<div class="col-sm-12 col-lg-6"
*ngIf="!loading && !error">
- <form class="form-horizontal"
- #frm="ngForm"
+ <form #frm="ngForm"
[formGroup]="userForm"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 i18n="form title|Example: Create Pool@@formTitle"
- class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3>
- </div>
- <div class="panel-body">
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
<!-- Username -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('uid', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('uid', frm)}">
+ <label class="col-form-label col-sm-3"
for="uid">
<ng-container i18n>Username</ng-container>
<span class="required"
formControlName="uid"
[readonly]="editing"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('uid', frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('uid', frm, 'notUnique')"
i18n>The chosen user ID is already in use.</span>
</div>
</div>
<!-- Full name -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('display_name', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('display_name', frm)}">
+ <label class="col-form-label col-sm-3"
for="display_name">
<ng-container i18n>Full name</ng-container>
<span class="required"
class="form-control"
type="text"
formControlName="display_name">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('display_name', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Email address -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('email', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('email', frm)}">
+ <label class="col-form-label col-sm-3"
for="email"
i18n>Email address</label>
<div class="col-sm-9">
class="form-control"
type="text"
formControlName="email">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('email', frm, 'email')"
i18n>This is not a valid email address.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('email', frm, 'notUnique')"
i18n>The chosen email address is already in use.</span>
</div>
</div>
<!-- Max. buckets -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('max_buckets', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('max_buckets', frm)}">
+ <label class="col-form-label col-sm-3"
for="max_buckets">
<ng-container i18n>Max. buckets</ng-container>
<span class="required"></span>
class="form-control"
type="number"
formControlName="max_buckets">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('max_buckets', frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('max_buckets', frm, 'min')"
i18n>The entered value must be >= 0.</span>
</div>
</div>
<!-- Suspended -->
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="suspended"
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="suspended"
type="checkbox"
formControlName="suspended">
- <label for="suspended"
+ <label class="form-check-label"
+ for="suspended"
i18n>Suspended</label>
</div>
</div>
<legend i18n>S3 key</legend>
<!-- Auto-generate key -->
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="generate_key"
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="generate_key"
type="checkbox"
formControlName="generate_key">
- <label for="generate_key"
+ <label class="form-check-label"
+ for="generate_key"
i18n>Auto-generate key</label>
</div>
</div>
</div>
<!-- Access key -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('access_key', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('access_key', frm)}"
*ngIf="!editing && !userForm.getValue('generate_key')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="access_key">
<ng-container i18n>Access key</ng-container>
<span class="required"></span>
class="form-control"
type="password"
formControlName="access_key">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="access_key">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdCopy2ClipboardButton="access_key">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('access_key', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Secret key -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('secret_key', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('secret_key', frm)}"
*ngIf="!editing && !userForm.getValue('generate_key')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="secret_key">
<ng-container i18n>Secret key</ng-container>
<span class="required"></span>
class="form-control"
type="password"
formControlName="secret_key">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="secret_key">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdCopy2ClipboardButton="secret_key">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('secret_key', frm, 'required')"
i18n>This field is required.</span>
</div>
<!-- Subusers -->
<fieldset *ngIf="editing">
<legend i18n>Subusers</legend>
-
- <div class="col-sm-offset-3 col-sm-9">
- <span *ngIf="subusers.length === 0"
- class="form-control no-border">
- <span class="text-muted"
- i18n>There are no subusers.</span>
- </span>
-
- <span *ngFor="let subuser of subusers; let i=index;">
- <div class="input-group">
- <span class="input-group-addon">
- <i class="icon-prepend {{ icons.user }}"></i>
- </span>
- <input type="text"
- class="form-control"
- value="{{ subuser.id }}"
- readonly>
- <span class="input-group-addon"
- style="border-left: 0; border-right: 0;">
- <i class="icon-prepend {{ icons.share }}"></i>
- </span>
- <input type="text"
- class="form-control"
- value="{{ ('full-control' === subuser.permissions) ? 'full' : subuser.permissions }}"
- readonly>
- <span class="input-group-btn">
- <button type="button"
- class="btn btn-default tc_showSubuserButton"
- i18n-tooltip
- tooltip="Edit"
- (click)="showSubuserModal(i)">
- <i [ngClass]="[icons.edit]"></i>
- </button>
+ <div class="row">
+ <div class="offset-sm-3 col-sm-9">
+ <span *ngIf="subusers.length === 0"
+ class="form-control no-border">
+ <span class="form-text text-muted"
+ i18n>There are no subusers.</span>
+ </span>
+
+ <span *ngFor="let subuser of subusers; let i=index;">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <span class="input-group-text">
+ <i class="{{ icons.user }}"></i>
+ </span>
+ </div>
+ <input type="text"
+ class="form-control"
+ value="{{ subuser.id }}"
+ readonly>
+ <div class="input-group-prepend"
+ style="border-left: 0; border-right: 0;">
+ <span class="input-group-text">
+ <i class="{{ icons.share }}"></i>
+ </span>
+ </div>
+ <input type="text"
+ class="form-control"
+ value="{{ ('full-control' === subuser.permissions) ? 'full' : subuser.permissions }}"
+ readonly>
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light tc_showSubuserButton"
+ i18n-tooltip
+ tooltip="Edit"
+ (click)="showSubuserModal(i)">
+ <i [ngClass]="[icons.edit]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteSubuserButton"
+ i18n-tooltip
+ tooltip="Delete"
+ (click)="deleteSubuser(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"></span>
+ </span>
+
+ <div class="row">
+ <div class="col-12">
<button type="button"
- class="btn btn-default tc_deleteSubuserButton"
- i18n-tooltip
- tooltip="Delete"
- (click)="deleteSubuser(i)">
- <i [ngClass]="[icons.destroy]"></i>
+ class="btn btn-light float-right tc_addSubuserButton"
+ (click)="showSubuserModal()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>{{ actionLabels.CREATE | titlecase }}
+ {{ subuserLabel | upperFirst }}</ng-container>
</button>
- </span>
+ </div>
</div>
<span class="help-block"></span>
- </span>
-
- <span class="form-control no-border">
- <button type="button"
- class="btn btn-sm btn-default btn-label pull-right tc_addSubuserButton"
- (click)="showSubuserModal()">
- <i [ngClass]="[icons.add, icons.width]"></i>
- <ng-container i18n>{{ actionLabels.CREATE | titlecase }} {{ subuserLabel | upperFirst }}</ng-container>
- </button>
- </span>
+ </div>
</div>
</fieldset>
<legend i18n>Keys</legend>
<!-- S3 keys -->
- <label class="col-sm-3 control-label"
- i18n>S3</label>
- <div class="col-sm-9">
- <span *ngIf="s3Keys.length === 0"
- class="form-control no-border">
- <span class="text-muted"
- i18n>There are no keys.</span>
- </span>
-
- <span *ngFor="let key of s3Keys; let i=index;">
- <div class="input-group">
- <span class="input-group-addon">
- <i class="icon-prepend {{ icons.key }}"></i>
- </span>
- <input type="text"
- class="form-control"
- value="{{ key.user }}"
- readonly>
- <span class="input-group-btn">
- <button type="button"
- class="btn btn-default tc_showS3KeyButton"
- i18n-tooltip
- tooltip="Show"
- (click)="showS3KeyModal(i)">
- <i [ngClass]="[icons.show]"></i>
- </button>
+ <div class="form-group row">
+ <label class="col-sm-3 col-form-label"
+ i18n>S3</label>
+ <div class="col-sm-9">
+ <span *ngIf="s3Keys.length === 0"
+ class="form-control no-border">
+ <span class="form-text text-muted"
+ i18n>There are no keys.</span>
+ </span>
+
+ <span *ngFor="let key of s3Keys; let i=index;">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <div class="input-group-text">
+ <i class="{{ icons.key }}"></i>
+ </div>
+ </div>
+ <input type="text"
+ class="form-control"
+ value="{{ key.user }}"
+ readonly>
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light tc_showS3KeyButton"
+ i18n-tooltip
+ tooltip="Show"
+ (click)="showS3KeyModal(i)">
+ <i [ngClass]="[icons.show]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteS3KeyButton"
+ i18n-tooltip
+ tooltip="Delete"
+ (click)="deleteS3Key(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"></span>
+ </span>
+
+ <div class="row">
+ <div class="col-12">
<button type="button"
- class="btn btn-default tc_deleteS3KeyButton"
- i18n-tooltip
- tooltip="Delete"
- (click)="deleteS3Key(i)">
- <i [ngClass]="[icons.destroy]"></i>
+ class="btn btn-light float-right tc_addS3KeyButton"
+ (click)="showS3KeyModal()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>{{ actionLabels.CREATE | titlecase }}
+ {{ s3keyLabel | upperFirst }}</ng-container>
</button>
- </span>
+ </div>
</div>
+
<span class="help-block"></span>
- </span>
+ </div>
- <span class="form-control no-border">
- <button type="button"
- class="btn btn-sm btn-default btn-label pull-right tc_addS3KeyButton"
- (click)="showS3KeyModal()">
- <i [ngClass]="[icons.add, icons.width]"></i>
- <ng-container i18n>{{ actionLabels.CREATE | titlecase }} {{ s3keyLabel | upperFirst }}</ng-container>
- </button>
- </span>
<hr>
</div>
<!-- Swift keys -->
- <label class="col-sm-3 control-label"
- i18n>Swift</label>
- <div class="col-sm-9">
- <span *ngIf="swiftKeys.length === 0"
- class="form-control no-border">
- <span class="text-muted"
- i18n>There are no keys.</span>
- </span>
+ <div class="form-group row">
+ <label class="col-sm-3 col-form-label"
+ i18n>Swift</label>
- <span *ngFor="let key of swiftKeys; let i=index;">
- <div class="input-group">
- <span class="input-group-addon">
- <i class="icon-prepend {{ icons.key }}"></i>
- </span>
- <input type="text"
- class="form-control"
- value="{{ key.user }}"
- readonly>
- <span class="input-group-btn">
- <button type="button"
- class="btn btn-default tc_showSwiftKeyButton"
- i18n-tooltip
- tooltip="Show"
- (click)="showSwiftKeyModal(i)">
- <i [ngClass]="[icons.show]"></i>
- </button>
- </span>
- </div>
- <span class="help-block"></span>
- </span>
+ <div class="col-sm-9">
+ <span *ngIf="swiftKeys.length === 0"
+ class="form-control no-border">
+ <span class="form-text text-muted"
+ i18n>There are no keys.</span>
+ </span>
+
+ <span *ngFor="let key of swiftKeys; let i=index;">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <span class="input-group-text">
+ <i class="{{ icons.key }}"></i>
+ </span>
+ </div>
+ <input type="text"
+ class="form-control"
+ value="{{ key.user }}"
+ readonly>
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light tc_showSwiftKeyButton"
+ i18n-tooltip
+ tooltip="Show"
+ (click)="showSwiftKeyModal(i)">
+ <i [ngClass]="[icons.show]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"></span>
+ </span>
+ </div>
</div>
</fieldset>
<fieldset *ngIf="editing">
<legend i18n>Capabilities</legend>
- <div class="col-sm-offset-3 col-sm-9">
- <span *ngIf="capabilities.length === 0"
- class="form-control no-border">
- <span class="text-muted"
- i18n>There are no capabilities.</span>
- </span>
-
- <span *ngFor="let cap of capabilities; let i=index;">
- <div class="input-group">
- <span class="input-group-addon">
- <i class="icon-prepend {{ icons.share }}"></i>
- </span>
- <input type="text"
- class="form-control"
- value="{{ cap.type }}:{{ cap.perm }}"
- readonly>
- <span class="input-group-btn">
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
+ <span *ngIf="capabilities.length === 0"
+ class="form-control no-border">
+ <span class="form-text text-muted"
+ i18n>There are no capabilities.</span>
+ </span>
+
+ <span *ngFor="let cap of capabilities; let i=index;">
+ <div class="input-group">
+ <span class="input-group-prepend">
+ <div class="input-group-text">
+ <i class="{{ icons.share }}"></i>
+ </div>
+ </span>
+ <input type="text"
+ class="form-control"
+ value="{{ cap.type }}:{{ cap.perm }}"
+ readonly>
+ <span class="input-group-append">
+ <button type="button"
+ class="btn btn-light tc_editCapButton"
+ i18n-tooltip
+ tooltip="Edit"
+ (click)="showCapabilityModal(i)">
+ <i [ngClass]="[icons.edit]"></i>
+ </button>
+ <button type="button"
+ class="btn btn-light tc_deleteCapButton"
+ i18n-tooltip
+ tooltip="Delete"
+ (click)="deleteCapability(i)">
+ <i [ngClass]="[icons.destroy]"></i>
+ </button>
+ </span>
+ </div>
+ <span class="form-text text-muted"></span>
+ </span>
+
+ <div class="row">
+ <div class="col-12">
<button type="button"
- class="btn btn-default tc_editCapButton"
- i18n-tooltip
- tooltip="Edit"
- (click)="showCapabilityModal(i)">
- <i [ngClass]="[icons.edit]"></i>
+ class="btn btn-light float-right tc_addCapButton"
+ (click)="showCapabilityModal()">
+ <i [ngClass]="[icons.add]"></i>
+ <ng-container i18n>{{ actionLabels.ADD | titlecase }}
+ {{ capabilityLabel | upperFirst }}</ng-container>
</button>
- <button type="button"
- class="btn btn-default tc_deleteCapButton"
- i18n-tooltip
- tooltip="Delete"
- (click)="deleteCapability(i)">
- <i [ngClass]="[icons.destroy]"></i>
- </button>
- </span>
+ </div>
</div>
<span class="help-block"></span>
- </span>
-
- <span class="form-control no-border">
- <button type="button"
- class="btn btn-sm btn-default btn-label pull-right tc_addCapButton"
- (click)="showCapabilityModal()">
- <i [ngClass]="[icons.add, icons.width]"></i>
- <ng-container i18n>{{ actionLabels.ADD | titlecase }} {{ capabilityLabel | upperFirst }}</ng-container>
- </button>
- </span>
+ </div>
</div>
</fieldset>
<legend i18n>User quota</legend>
<!-- Enabled -->
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="user_quota_enabled"
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="user_quota_enabled"
type="checkbox"
formControlName="user_quota_enabled">
- <label for="user_quota_enabled"
+ <label class="form-check-label"
+ for="user_quota_enabled"
i18n>Enabled</label>
</div>
</div>
</div>
<!-- Unlimited size -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="userForm.controls.user_quota_enabled.value">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="user_quota_max_size_unlimited"
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="user_quota_max_size_unlimited"
type="checkbox"
formControlName="user_quota_max_size_unlimited">
- <label for="user_quota_max_size_unlimited"
+ <label class="form-check-label"
+ for="user_quota_max_size_unlimited"
i18n>Unlimited size</label>
</div>
</div>
</div>
<!-- Maximum size -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('user_quota_max_size', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('user_quota_max_size', frm)}"
*ngIf="userForm.controls.user_quota_enabled.value && !userForm.getValue('user_quota_max_size_unlimited')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="user_quota_max_size">
<ng-container i18n>Max. size</ng-container>
<span class="required"></span>
type="text"
formControlName="user_quota_max_size"
cdDimlessBinary>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('user_quota_max_size', frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('user_quota_max_size', frm, 'quotaMaxSize')"
i18n>The value is not valid.</span>
</div>
</div>
<!-- Unlimited objects -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="userForm.controls.user_quota_enabled.value">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="user_quota_max_objects_unlimited"
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="user_quota_max_objects_unlimited"
type="checkbox"
formControlName="user_quota_max_objects_unlimited">
- <label for="user_quota_max_objects_unlimited"
+ <label class="form-check-label"
+ for="user_quota_max_objects_unlimited"
i18n>Unlimited objects</label>
</div>
</div>
</div>
<!-- Maximum objects -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('user_quota_max_objects', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('user_quota_max_objects', frm)}"
*ngIf="userForm.controls.user_quota_enabled.value && !userForm.getValue('user_quota_max_objects_unlimited')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="user_quota_max_objects">
<ng-container i18n>Max. objects</ng-container>
<span class="required"></span>
class="form-control"
type="number"
formControlName="user_quota_max_objects">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('user_quota_max_objects', frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('user_quota_max_objects', frm, 'min')"
i18n>The entered value must be >= 0.</span>
</div>
<legend i18n>Bucket quota</legend>
<!-- Enabled -->
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="bucket_quota_enabled"
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="bucket_quota_enabled"
type="checkbox"
formControlName="bucket_quota_enabled">
- <label for="bucket_quota_enabled"
+ <label class="form-check-label"
+ for="bucket_quota_enabled"
i18n>Enabled</label>
</div>
</div>
</div>
<!-- Unlimited size -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="userForm.controls.bucket_quota_enabled.value">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="bucket_quota_max_size_unlimited"
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="bucket_quota_max_size_unlimited"
type="checkbox"
formControlName="bucket_quota_max_size_unlimited">
- <label for="bucket_quota_max_size_unlimited"
+ <label class="form-check-label"
+ for="bucket_quota_max_size_unlimited"
i18n>Unlimited size</label>
</div>
</div>
</div>
<!-- Maximum size -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('bucket_quota_max_size', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('bucket_quota_max_size', frm)}"
*ngIf="userForm.controls.bucket_quota_enabled.value && !userForm.getValue('bucket_quota_max_size_unlimited')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="bucket_quota_max_size">
<ng-container i18n>Max. size</ng-container>
<span class="required"></span>
type="text"
formControlName="bucket_quota_max_size"
cdDimlessBinary>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('bucket_quota_max_size', frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('bucket_quota_max_size', frm, 'quotaMaxSize')"
i18n>The value is not valid.</span>
</div>
</div>
<!-- Unlimited objects -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="userForm.controls.bucket_quota_enabled.value">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="bucket_quota_max_objects_unlimited"
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="bucket_quota_max_objects_unlimited"
type="checkbox"
formControlName="bucket_quota_max_objects_unlimited">
- <label for="bucket_quota_max_objects_unlimited"
+ <label class="form-check-label"
+ for="bucket_quota_max_objects_unlimited"
i18n>Unlimited objects</label>
</div>
</div>
</div>
<!-- Maximum objects -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('bucket_quota_max_objects', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('bucket_quota_max_objects', frm)}"
*ngIf="userForm.controls.bucket_quota_enabled.value && !userForm.getValue('bucket_quota_max_objects_unlimited')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="bucket_quota_max_objects">
<ng-container i18n>Max. objects</ng-container>
<span class="required"></span>
class="form-control"
type="number"
formControlName="bucket_quota_max_objects">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('bucket_quota_max_objects', frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('bucket_quota_max_objects', frm, 'min')"
i18n>The entered value must be >= 0.</span>
</div>
</fieldset>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
- <cd-submit-button
- (submitAction)="onSubmit()"
- [form]="userForm"
- i18n="form action button|Example: Create Pool@@formActionButton"
- type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="onSubmit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="userForm">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
-@import '../../../../defaults';
-
-form .input-group-addon {
- color: $color-rgw-icon !important;
- background-color: transparent;
-}
<div class="modal-header">
<h4 i18n="form title|Example: Create Pool@@formTitle"
- class="modal-title pull-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+ class="modal-title float-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+
<button type="button"
- class="close pull-right"
+ class="close float-right"
aria-label="Close"
(click)="bsModalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
-<form class="form-horizontal"
- #frm="ngForm"
+<form #frm="ngForm"
[formGroup]="formGroup"
novalidate>
<div class="modal-body">
<!-- Username -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('user', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('user', frm)}">
+ <label class="col-form-label col-sm-3"
for="user">
<ng-container i18n>Username</ng-container>
<span class="required"
<option *ngFor="let userCandidate of userCandidates"
[value]="userCandidate">{{ userCandidate }}</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('user', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Auto-generate key -->
- <div class="form-group"
+ <div class="form-group row"
*ngIf="!viewing">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="generate_key"
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="generate_key"
type="checkbox"
formControlName="generate_key">
- <label for="generate_key"
+ <label class="form-check-label"
+ for="generate_key"
i18n>Auto-generate key</label>
</div>
</div>
</div>
<!-- Access key -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('access_key', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('access_key', frm)}"
*ngIf="!formGroup.getValue('generate_key')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="access_key">
<ng-container i18n>Access key</ng-container>
<span class="required"
type="password"
[readonly]="viewing"
formControlName="access_key">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="access_key">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdCopy2ClipboardButton="access_key">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('access_key', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Secret key -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('secret_key', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('secret_key', frm)}"
*ngIf="!formGroup.getValue('generate_key')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="secret_key">
<ng-container i18n>Secret key</ng-container>
<span class="required"
type="password"
[readonly]="viewing"
formControlName="secret_key">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="secret_key">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdCopy2ClipboardButton="secret_key">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('secret_key', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
<div class="modal-footer">
- <cd-submit-button
- *ngIf="!viewing"
- (submitAction)="onSubmit()"
- i18n="form action button|Example: Create Pool@@formActionButton"
- [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button *ngIf="!viewing"
+ (submitAction)="onSubmit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button [back]="bsModalRef.hide"></cd-back-button>
</div>
</form>
<div class="modal-header">
<h4 i18n="form title|Example: Create Pool@@formTitle"
- class="modal-title pull-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+ class="modal-title float-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
<button type="button"
- class="close pull-right"
+ class="close float-right"
aria-label="Close"
(click)="bsModalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
-<form class="form-horizontal"
- #frm="ngForm"
+<form #frm="ngForm"
[formGroup]="formGroup"
novalidate>
<div class="modal-body">
<!-- Username -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('uid', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('uid', frm)}">
+ <label class="col-form-label col-sm-3"
for="uid"
i18n>Username</label>
<div class="col-sm-9">
</div>
<!-- Subuser -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('subuid', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('subuid', frm)}">
+ <label class="col-form-label col-sm-3"
for="subuid">
<ng-container i18n>Subuser</ng-container>
<span class="required"
formControlName="subuid"
[readonly]="editing"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('subuid', frm, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('subuid', frm, 'subuserIdExists')"
i18n>The chosen subuser ID is already in use.</span>
</div>
</div>
<!-- Permission -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('perm', frm)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('perm', frm)}">
+ <label class="col-form-label col-sm-3"
for="perm">
<ng-container i18n>Permission</ng-container>
<span class="required"></span>
<option i18n
value="full-control">full</option>
</select>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('perm', frm, 'required')"
i18n>This field is required.</span>
</div>
<legend i18n>Swift key</legend>
<!-- Auto-generate key -->
- <div class="form-group">
- <div class="col-sm-offset-3 col-sm-9">
- <div class="checkbox checkbox-primary">
- <input id="generate_secret"
+ <div class="form-group row">
+ <div class="offset-sm-3 col-sm-9">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="generate_secret"
type="checkbox"
formControlName="generate_secret">
- <label for="generate_secret"
+ <label class="form-check-label"
+ for="generate_secret"
i18n>Auto-generate secret</label>
</div>
</div>
</div>
<!-- Secret key -->
- <div class="form-group"
- [ngClass]="{'has-error': formGroup.showError('secret_key', frm)}"
+ <div class="form-group row"
+ [ngClass]="{':invalid': formGroup.showError('secret_key', frm)}"
*ngIf="!editing && !formGroup.getValue('generate_secret')">
- <label class="control-label col-sm-3"
+ <label class="col-form-label col-sm-3"
for="secret_key">
<ng-container i18n>Secret key</ng-container>
<span class="required"></span>
class="form-control"
type="password"
formControlName="secret_key">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="secret_key">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdCopy2ClipboardButton="secret_key">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="formGroup.showError('secret_key', frm, 'required')"
i18n>This field is required.</span>
</div>
</div>
<div class="modal-footer">
- <cd-submit-button
- (submitAction)="onSubmit()"
- i18n="form action button|Example: Create Pool@@formActionButton"
- [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="onSubmit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="formGroup">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button [back]="bsModalRef.hide"></cd-back-button>
</div>
</form>
<div class="modal-header">
<h4 i18n="form title|Example: Create Pool@@formTitle"
- class="modal-title pull-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+ class="modal-title float-left">{{ action | titlecase }} {{ resource | upperFirst }}</h4>
+
<button type="button"
- class="close pull-right"
+ class="close float-right"
aria-label="Close"
(click)="bsModalRef.hide()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
- <form class="form-horizontal"
- novalidate>
+ <form novalidate>
<!-- Username -->
- <div class="form-group">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="user"
i18n>Username</label>
<div class="col-sm-9">
</div>
<!-- Secret key -->
- <div class="form-group">
- <label class="control-label col-sm-3"
+ <div class="form-group row">
+ <label class="col-form-label col-sm-3"
for="secret_key"
i18n>Secret key</label>
<div class="col-sm-9">
type="password"
[(ngModel)]="secret_key"
[readonly]="true">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="secret_key">
</button>
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdCopy2ClipboardButton="secret_key">
</button>
</span>
import { FormsModule } from '@angular/forms';
import { RouterTestingModule } from '@angular/router/testing';
-import { ToastModule } from 'ng2-toastr';
import { BsModalRef } from 'ngx-bootstrap/modal';
+import { ToastrModule } from 'ngx-toastr';
import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
import { SharedModule } from '../../../shared/shared.module';
configureTestBed({
declarations: [RgwUserSwiftKeyModalComponent],
- imports: [ToastModule.forRoot(), FormsModule, SharedModule, RouterTestingModule],
+ imports: [ToastrModule.forRoot(), FormsModule, SharedModule, RouterTestingModule],
providers: [BsModalRef, i18nProviders]
});
<div class="col-sm-6 hidden-xs">
<img src="assets/Ceph_Logo_Stacked_RGB_White_120411_fa_256x256.png"
alt="Ceph"
- class="pull-right">
+ class="float-right">
</div>
- <div class="col-xs-10 col-sm-4 col-lg-3 col-xs-offset-1 col-sm-offset-0 col-md-offset-0 col-lg-offset-0">
+ <div class="col-10 col-sm-4 col-lg-3 offset-1 offset-sm-0 offset-md-0 offset-lg-0">
<h1 i18n="The welcome message on the login page">Welcome to Ceph!</h1>
<form name="loginForm"
(ngSubmit)="login()"
<!-- Username -->
<div class="form-group has-feedback"
- [ngClass]="{'has-error': (loginForm.submitted || username.dirty) && username.invalid}">
+ [ngClass]="{':invalid': (loginForm.submitted || username.dirty) && username.invalid}">
<input name="username"
[(ngModel)]="model.username"
#username="ngModel"
class="form-control"
required
autofocus>
- <div class="help-block"
+ <div class="form-text text-muted"
*ngIf="(loginForm.submitted || username.dirty) && username.invalid"
i18n>Username is required</div>
</div>
<!-- Password -->
<div class="form-group has-feedback"
- [ngClass]="{'has-error': (loginForm.submitted || password.dirty) && password.invalid}">
+ [ngClass]="{':invalid': (loginForm.submitted || password.dirty) && password.invalid}">
<div class="input-group">
<input id="password"
name="password"
placeholder="Enter your password..."
class="form-control"
required>
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default btn-password"
+ class="btn btn-outline-light btn-password"
cdPasswordButton="password">
</button>
</span>
</div>
- <div class="help-block"
+ <div class="form-text text-muted"
*ngIf="(loginForm.submitted || password.dirty) && password.invalid"
i18n>Password is required</div>
</div>
<input type="submit"
- class="btn btn-primary btn-block"
+ class="btn btn-secondary btn-block"
[disabled]="loginForm.invalid"
value="Login"
i18n-value>
-@import '../../../../defaults';
+@import 'defaults';
::ng-deep .login {
height: 100%;
.btn-password:focus {
outline-color: $color-password-toggle-focus;
}
+}
- .checkbox-primary input[type='checkbox']:checked + label::before,
- .checkbox-primary input[type='radio']:checked + label::before {
- background-color: $color-login-checkbox-bg;
- border-color: $color-login-checkbox-border;
+// This will override the colors applied by chrome
+@keyframes autofill {
+ to {
+ color: $color-password-toggle-text;
+ background-color: $color-password-toggle-bg;
}
}
+
+input:-webkit-autofill {
+ animation-name: autofill;
+ animation-fill-mode: both;
+}
-@import '../../../../defaults';
+@import 'defaults';
thead {
background-color: $color-table-header-bg;
<div class="col-sm-12 col-lg-6">
<form name="roleForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="roleForm"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 i18n="form title|Example: Create Pool@@formTitle"
- class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3>
- </div>
- <div class="panel-body">
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
<!-- Name -->
- <div class="form-group"
- [ngClass]="{'has-error': roleForm.showError('name', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': roleForm.showError('name', formDir)}">
+ <label class="col-form-label col-sm-3"
for="name">
<ng-container i18n>Name</ng-container>
<span class="required"
name="name"
formControlName="name"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="roleForm.showError('name', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="roleForm.showError('name', formDir, 'notUnique')"
i18n>The chosen name is already in use.</span>
</div>
</div>
<!-- Description -->
- <div class="form-group"
- [ngClass]="{'has-error': roleForm.showError('description', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': roleForm.showError('description', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="description">Description</label>
<div class="col-sm-9">
<input class="form-control"
</div>
<!-- Permissions -->
- <div class="form-group">
+ <div class="form-group row">
<label i18n
- class="control-label col-sm-3">Permissions</label>
+ class="col-form-label col-sm-3">Permissions</label>
<div class="col-sm-9">
<cd-table [data]="scopes_permissions"
[columns]="columns"
</div>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
- <cd-submit-button
- [form]="formDir" (submitAction)="submit()"
- i18n="form action button|Example: Create Pool@@formActionButton"
- type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="submit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="formDir">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
let-column="column"
let-row="row"
let-value="value">
- <div class="checkbox checkbox-primary">
- <input id="scope_{{ row.scope }}"
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="scope_{{ row.scope }}"
type="checkbox"
[checked]="isRowChecked(row.scope)"
(change)="onClickCellCheckbox(row.scope, column.prop, $event)">
- <label class="datatable-permissions-scope-cell-label"
+ <label class="datatable-permissions-scope-cell-label form-check-label"
for="scope_{{ row.scope }}">{{ value }}</label>
</div>
</ng-template>
let-column="column"
let-row="row"
let-value="value">
- <div class="checkbox checkbox-primary">
- <input type="checkbox"
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ type="checkbox"
[checked]="value"
+ [id]="row.scope + '-' + column.prop"
(change)="onClickCellCheckbox(row.scope, column.prop, $event)">
- <label></label>
+ <label class="form-check-label"
+ [for]="row.scope + '-' + column.prop"></label>
</div>
</ng-template>
<ng-template #headerPermissionCheckboxTpl
let-column="column">
- <div class="checkbox checkbox-primary">
- <input id="header_{{ column.prop }}"
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ id="header_{{ column.prop }}"
type="checkbox"
[checked]="isHeaderChecked(column.prop)"
(change)="onClickHeaderCheckbox(column.prop, $event)">
- <label class="datatable-permissions-header-cell-label"
+ <label class="datatable-permissions-header-cell-label form-check-label"
for="header_{{ column.prop }}">{{ column.name }}</label>
</div>
</ng-template>
<h1 i18n>Sorry, the user does not exist in Ceph.</h1>
<h4 i18n>Return to <a class="sso-logout" [href]="logoutUrl">Login Page</a>. You'll be logged out from the Identity Provider when you retry logging in.</h4>
- <img class="img-responsive center-block img-rounded"
+ <img class="img-fluid mx-auto rounded"
src="/assets/1280px-Nautilus_Octopus.jpg">
<span>
"<a href="https://www.flickr.com/photos/146401137@N06/40335060661">Nautilus Octopus</a>" by Jin Kemoole is licensed under
<div class="col-sm-12 col-lg-6">
<form name="userForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="userForm"
novalidate>
- <div class="panel panel-default">
- <div class="panel-heading">
- <h3 i18n="form title|Example: Create Pool@@formTitle"
- class="panel-title">{{ action | titlecase }} {{ resource | upperFirst }}</h3>
- </div>
- <div class="panel-body">
+ <div class="card">
+ <div i18n="form title|Example: Create Pool@@formTitle"
+ class="card-header">{{ action | titlecase }} {{ resource | upperFirst }}</div>
+ <div class="card-body">
<!-- Username -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('username', formDir)}">
- <label class="control-label col-sm-3"
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('username', formDir)}">
+ <label class="col-form-label col-sm-3"
for="username">
<ng-container i18n>Username</ng-container>
<span class="required"
name="username"
formControlName="username"
autofocus>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('username', formDir, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Password -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('password', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('password', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="password">Password</label>
<div class="col-sm-9">
<div class="input-group">
name="password"
autocomplete="new-password"
formControlName="password">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="password">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('password', formDir, 'required')"
i18n>This field is required.</span>
</div>
</div>
<!-- Confirm password -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('confirmpassword', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('confirmpassword', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="confirmpassword">Confirm password</label>
<div class="col-sm-9">
<div class="input-group">
id="confirmpassword"
name="confirmpassword"
formControlName="confirmpassword">
- <span class="input-group-btn">
+ <span class="input-group-append">
<button type="button"
- class="btn btn-default"
+ class="btn btn-light"
cdPasswordButton="confirmpassword">
</button>
</span>
</div>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('confirmpassword', formDir, 'required')"
i18n>This field is required.</span>
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('confirmpassword', formDir, 'match')"
i18n>Password confirmation doesn't match the password.</span>
</div>
</div>
<!-- Name -->
- <div class="form-group">
+ <div class="form-group row">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="name">Full name</label>
<div class="col-sm-9">
<input class="form-control"
</div>
<!-- Email -->
- <div class="form-group"
- [ngClass]="{'has-error': userForm.showError('email', formDir)}">
+ <div class="form-group row"
+ [ngClass]="{':invalid': userForm.showError('email', formDir)}">
<label i18n
- class="control-label col-sm-3"
+ class="col-form-label col-sm-3"
for="email">Email</label>
<div class="col-sm-9">
<input class="form-control"
name="email"
formControlName="email">
- <span class="help-block"
+ <span class="form-text text-muted"
*ngIf="userForm.showError('email', formDir, 'email')"
i18n>Invalid email.</span>
</div>
</div>
<!-- Roles -->
- <label class="col-sm-3 control-label"
- i18n>Roles</label>
- <div class="col-sm-9">
- <span class="form-control no-border full-height"
- *ngIf="allRoles">
- <cd-select-badges [data]="userForm.controls.roles.value"
- [options]="allRoles"
- [messages]="messages"></cd-select-badges>
- </span>
+ <div class="form-group row">
+ <label class="col-sm-3 col-form-label"
+ i18n>Roles</label>
+ <div class="col-sm-9">
+ <span class="no-border full-height"
+ *ngIf="allRoles">
+ <cd-select-badges [data]="userForm.controls.roles.value"
+ [options]="allRoles"
+ [messages]="messages"></cd-select-badges>
+ </span>
+ </div>
+
</div>
</div>
- <div class="panel-footer">
+ <div class="card-footer">
<div class="button-group text-right">
- <cd-submit-button
- [form]="formDir"
- (submitAction)="submit()"
- i18n="form action button|Example: Create Pool@@formActionButton"
- type="button">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
+ <cd-submit-button (submitAction)="submit()"
+ i18n="form action button|Example: Create Pool@@formActionButton"
+ [form]="formDir">{{ action | titlecase }} {{ resource | upperFirst }}</cd-submit-button>
<cd-back-button></cd-back-button>
</div>
</div>
<tab heading="Users"
i18n-heading
[active]="url === '/user-management/users'"
- (select)="navigateTo('/user-management/users')">
+ (selectTab)="navigateTo('/user-management/users')">
</tab>
<tab heading="Roles"
i18n-heading
[active]="url === '/user-management/roles'"
- (select)="navigateTo('/user-management/roles')">
+ (selectTab)="navigateTo('/user-management/roles')">
</tab>
</tabset>
<div class="modal-header">
<button type="button"
- class="close pull-right"
+ class="close float-right"
aria-label="Close"
(click)="modalRef.hide()">
<span aria-hidden="true">×</span>
<br>
<ul class="list-unstyled">
<li class="row">
- <strong class="col-xs-6 col-sm-4">Ceph Manager</strong>
- <span class="col-xs-4 col-sm-4">{{ hostAddr }}</span>
+ <strong class="col-6 col-sm-4">Ceph Manager</strong>
+ <span class="col-4 col-sm-4">{{ hostAddr }}</span>
</li>
<li class="row">
- <strong class="col-xs-6 col-sm-4">User</strong>
- <span class="col-xs-4 col-sm-4">{{ modalVariables.user }}</span>
+ <strong class="col-6 col-sm-4">User</strong>
+ <span class="col-4 col-sm-4">{{ modalVariables.user }}</span>
</li>
<li class="row">
- <strong class="col-xs-6 col-sm-4">User Role</strong>
- <span class="col-xs-4 col-sm-4">{{ modalVariables.role }}</span>
+ <strong class="col-6 col-sm-4">User Role</strong>
+ <span class="col-4 col-sm-4">{{ modalVariables.role }}</span>
</li>
<li class="row">
- <strong class="col-xs-6 col-sm-4">Browser</strong>
- <span class="col-xs-4 col-sm-4">{{ modalVariables.browserName }}</span>
+ <strong class="col-6 col-sm-4">Browser</strong>
+ <span class="col-4 col-sm-4">{{ modalVariables.browserName }}</span>
</li>
<li class="row">
- <strong class="col-xs-6 col-sm-4">Browser Version</strong>
- <span class="col-xs-4 col-sm-4">{{ modalVariables.browserVersion }}</span>
+ <strong class="col-6 col-sm-4">Browser Version</strong>
+ <span class="col-4 col-sm-4">{{ modalVariables.browserVersion }}</span>
</li>
<li class="row">
- <strong class="col-xs-6 col-sm-4">Browser OS</strong>
- <span class="col-xs-4 col-sm-4">{{ modalVariables.browserOS }}</span>
+ <strong class="col-6 col-sm-4">Browser OS</strong>
+ <span class="col-4 col-sm-4">{{ modalVariables.browserOS }}</span>
</li>
</ul>
</div>
<div dropdown
+ class="btn-group"
*ngIf="userPermission.read">
<a dropdownToggle
class="dropdown-toggle"
- data-toggle="dropdown"
i18n-title
title="Dashboard Settings">
- <i [ngClass]="[icons.deepCheck, icons.width]"></i>
+ <i [ngClass]="[icons.deepCheck]"></i>
<span i18n
- class="visible-xs-inline-block">Dashboard Settings</span>
- <span class="caret"></span>
+ class="d-md-none">Dashboard Settings</span>
</a>
<ul *dropdownMenu
- class="dropdown-menu dropdown-menu-right">
+ class="dropdown-menu dropdown-menu-right"
+ role="menu">
<li *ngIf="userPermission.read">
<a i18n
class="dropdown-item"
-@import '../../../../defaults';
+@import 'defaults';
.breadcrumb {
padding: 8px 0;
-<form #docsForm action="/docs" target="_blank" method="post">
- <input type="hidden" name="token"/>
+<form #docsForm
+ action="/docs"
+ target="_blank"
+ method="post">
+ <input type="hidden"
+ name="token" />
</form>
-<div dropdown>
+<div class="btn-group"
+ dropdown>
<a dropdownToggle
class="dropdown-toggle"
- data-toggle="dropdown"
i18n-title
title="Help">
- <i [ngClass]="[icons.questionCircle, icons.width]"></i>
+ <i [ngClass]="[icons.questionCircle]"></i>
<span i18n
- class="visible-xs-inline-block">Help</span>
- <span class="caret"></span>
+ class="d-md-none">Help</span>
</a>
<ul *dropdownMenu
- class="dropdown-menu dropdown-menu-right">
+ class="dropdown-menu dropdown-menu-right"
+ role="menu">
<li>
<a i18n
class="dropdown-item"
openAboutModal() {
this.modalRef = this.modalService.show(AboutComponent);
+ this.modalRef.setClass('modal-lg');
}
goToApiDocs() {
-<div dropdown>
+<div dropdown
+ class="btn-group">
<a dropdownToggle
class="dropdown-toggle"
- data-toggle="dropdown"
i18n-title
title="Logged in user">
- <i [ngClass]="[icons.user, icons.width]"></i>
+ <i [ngClass]="[icons.user]"></i>
<span i18n
- class="visible-xs-inline-block">Logged in user</span>
- <span class="caret"></span>
+ class="d-md-none">Logged in user</span>
</a>
<ul *dropdownMenu
class="dropdown-menu dropdown-menu-right"
href="#">Signed in as
<strong>{{ username }}</strong></a>
</li>
- <li class="divider dropdown-divider"></li>
+ <li class="dropdown-divider"></li>
<li role="menuitem">
<a class="dropdown-item"
(click)="logout()">
- <i [ngClass]="[icons.signOut, icons.width]"></i>
+ <i [ngClass]="[icons.signOut]"></i>
<span i18n>Sign out</span>
</a>
</li>
-<nav class="navbar navbar-default navbar-main">
- <!-- Brand and toggle get grouped for better mobile display -->
-
- <div class="navbar-header tc_logo_component">
- <a class="navbar-brand"
+<div class="cd-navbar-top">
+ <nav class="navbar navbar-expand-md navbar-dark cd-navbar-brand">
+ <a class="navbar-brand mt-3 mb-2 ml-2"
href="#">
<img src="assets/Ceph_Logo_Standard_RGB_White_120411_fa.png"
- alt="Ceph">
+ alt="Ceph" />
</a>
<button type="button"
- class="navbar-toggle collapsed"
+ class="navbar-toggler"
(click)="isCollapsed = !isCollapsed">
<span i18n
class="sr-only">Toggle navigation</span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
- <span class="icon-bar"></span>
+ <span class="">
+ <i class="fa fa-navicon fa-lg"></i>
+ </span>
</button>
- </div>
- <!-- Collect the nav links, forms, and other content for toggling -->
- <div *ngIf="enabledFeature$ | async as enabledFeature"
- class="collapse navbar-collapse"
- id="bs-example-navbar-collapse-1"
- [collapse]="isCollapsed">
- <ul class="nav navbar-nav navbar-primary">
+ <div class="collapse navbar-collapse"
+ [collapse]="isCollapsed">
+ <ul class="navbar-nav mt-2 cd-navbar-primary d-block d-md-none">
+ <ng-container *ngTemplateOutlet="cd_menu"> </ng-container>
+ </ul>
+
+ <ul class="nav navbar-nav cd-navbar-utility my-2 my-md-0">
+ <ng-container *ngTemplateOutlet="cd_utilities"> </ng-container>
+ </ul>
+
+ </div>
+ </nav>
+
+ <nav class="navbar navbar-expand-md navbar-dark cd-navbar-main pb-0 pl-0 d-none d-md-flex">
+ <ul class="navbar-nav mr-auto my-0 cd-navbar-primary ">
+ <ng-container *ngTemplateOutlet="cd_menu"> </ng-container>
+ </ul>
+ </nav>
+</div>
+
+<ng-template #cd_utilities>
+ <li class="nav-item ">
+ <cd-language-selector class="cd-navbar"></cd-language-selector>
+ </li>
+ <li class="nav-item ">
+ <cd-task-manager class="cd-navbar"></cd-task-manager>
+ </li>
+ <li class="nav-item ">
+ <cd-notifications class="cd-navbar"></cd-notifications>
+ </li>
+ <li class="nav-item ">
+ <cd-dashboard-help class="cd-navbar"></cd-dashboard-help>
+ </li>
+ <li class="nav-item ">
+ <cd-administration class="cd-navbar"></cd-administration>
+ </li>
+ <li class="nav-item ">
+ <cd-identity class="cd-navbar"></cd-identity>
+ </li>
+</ng-template>
+
+<ng-template #cd_menu>
+ <!-- Dashboard -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_dashboard">
+ <a routerLink="/dashboard"
+ class="nav-link">
+ <i [ngClass]="[icons.health]"
+ [ngStyle]="summaryData?.health_status | healthColor"></i>
+ <span i18n>Dashboard</span>
+ </a>
+ </li>
- <!-- Dashboard -->
+ <!-- Cluster -->
+ <li dropdown
+ routerLinkActive="active"
+ class="nav-item dropdown tc_menuitem_cluster"
+ *ngIf="
+ permissions.hosts.read ||
+ permissions.monitor.read ||
+ permissions.osd.read ||
+ permissions.configOpt.read">
+ <a dropdownToggle
+ class="nav-link dropdown-toggle"
+ data-toggle="dropdown">
+ <ng-container i18n>Cluster</ng-container>
+ </a>
+ <ul *dropdownMenu
+ class="dropdown-menu">
<li routerLinkActive="active"
- class="tc_menuitem tc_menuitem_dashboard">
- <a routerLink="/dashboard">
- <i [ngClass]="[icons.health, icons.width]"
- [ngStyle]="summaryData?.health_status | healthColor"></i>
- <span i18n>Dashboard</span>
- </a>
+ class="tc_submenuitem tc_submenuitem_hosts"
+ *ngIf="permissions.hosts.read">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/hosts">Hosts</a>
</li>
-
- <!-- Cluster -->
- <li dropdown
- routerLinkActive="active"
- class="dropdown tc_menuitem tc_menuitem_cluster"
- *ngIf="permissions.hosts.read || permissions.monitor.read || permissions.osd.read || permissions.configOpt.read">
- <a dropdownToggle
- class="dropdown-toggle"
- data-toggle="dropdown">
- <ng-container i18n>Cluster</ng-container>
- <span class="caret"></span>
- </a>
- <ul *dropdownMenu
- class="dropdown-menu">
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_hosts"
- *ngIf="permissions.hosts.read">
- <a i18n
- class="dropdown-item"
- routerLink="/hosts">Hosts</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_cluster_monitor"
- *ngIf="permissions.monitor.read">
- <a i18n
- class="dropdown-item"
- routerLink="/monitor/">Monitors</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_hosts"
- *ngIf="permissions.osd.read">
- <a i18n
- class="dropdown-item"
- routerLink="/osd">OSDs</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_configuration"
- *ngIf="permissions.configOpt.read">
- <a i18n
- class="dropdown-item"
- routerLink="/configuration">Configuration</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_crush"
- *ngIf="permissions.hosts.read && permissions.osd.read">
- <a i18n
- class="dropdown-item"
- routerLink="/crush-map">CRUSH map</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_modules"
- *ngIf="permissions.configOpt.read">
- <a i18n
- class="dropdown-item"
- routerLink="/mgr-modules">Manager modules</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_log"
- *ngIf="permissions.log.read">
- <a i18n
- class="dropdown-item"
- routerLink="/logs">Logs</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_prometheus"
- *ngIf="prometheusConfigured && permissions.prometheus.read">
- <a i18n
- routerLink="/alerts">Alerts</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_prometheus"
- *ngIf="prometheusConfigured && permissions.prometheus.read">
- <a i18n
- routerLink="/silence">Silences</a>
- </li>
- </ul>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_cluster_monitor"
+ *ngIf="permissions.monitor.read">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/monitor/">Monitors</a>
</li>
-
- <!-- Pools -->
<li routerLinkActive="active"
- class="tc_menuitem tc_menuitem_pool"
- *ngIf="permissions.pool.read">
+ class="tc_submenuitem tc_submenuitem_hosts"
+ *ngIf="permissions.osd.read">
<a i18n
- routerLink="/pool">Pools</a>
+ class="dropdown-item"
+ routerLink="/osd">OSDs</a>
</li>
-
- <!-- Block -->
- <li dropdown
- routerLinkActive="active"
- class="dropdown tc_menuitem tc_menuitem_block"
- *ngIf="
- (enabledFeature.rbd || enabledFeature.mirroring || enabledFeature.iscsi) &&
- (permissions.rbdImage.read || permissions.rbdMirroring.read || permissions.iscsi.read)">
- <a dropdownToggle
- class="dropdown-toggle"
- data-toggle="dropdown"
- [ngStyle]="blockHealthColor()">
- <ng-container i18n>Block</ng-container>
- <span class="caret"></span>
- </a>
-
- <ul class="dropdown-menu">
- <li routerLinkActive="active"
- *ngIf="enabledFeature.rbd && permissions.rbdImage.read">
- <a i18n
- class="dropdown-item"
- routerLink="/block/rbd">Images</a>
- </li>
-
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_block_mirroring"
- *ngIf="enabledFeature.mirroring && permissions.rbdMirroring.read">
- <a class="dropdown-item"
- routerLink="/block/mirroring">
- <ng-container i18n>Mirroring</ng-container>
- <small *ngIf="summaryData?.rbd_mirroring?.warnings !== 0"
- class="label label-warning">{{ summaryData?.rbd_mirroring?.warnings }}</small>
- <small *ngIf="summaryData?.rbd_mirroring?.errors !== 0"
- class="label label-danger">{{ summaryData?.rbd_mirroring?.errors }}</small>
- </a>
- </li>
-
- <li routerLinkActive="active"
- *ngIf="enabledFeature.iscsi && permissions.iscsi.read">
- <a i18n
- class="dropdown-item"
- routerLink="/block/iscsi">iSCSI</a>
- </li>
- </ul>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_configuration"
+ *ngIf="permissions.configOpt.read">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/configuration">Configuration</a>
</li>
-
- <!-- NFS -->
<li routerLinkActive="active"
- class="tc_menuitem tc_menuitem_nfs"
- *ngIf="permissions?.nfs?.read">
+ class="tc_submenuitem tc_submenuitem_crush"
+ *ngIf="permissions.hosts.read && permissions.osd.read">
<a i18n
- routerLink="/nfs">NFS</a>
+ class="dropdown-item"
+ routerLink="/crush-map">CRUSH map</a>
</li>
-
- <!-- Filesystem -->
<li routerLinkActive="active"
- class="tc_menuitem tc_menuitem_cephs"
- *ngIf="enabledFeature.cephfs && permissions.cephfs.read">
+ class="tc_submenuitem tc_submenuitem_modules"
+ *ngIf="permissions.configOpt.read">
<a i18n
- routerLink="/cephfs">Filesystems</a>
+ class="dropdown-item"
+ routerLink="/mgr-modules">Manager modules</a>
</li>
-
- <!-- Object Gateway -->
- <li dropdown
- routerLinkActive="active"
- class="dropdown tc_menuitem tc_menuitem_rgw"
- *ngIf="enabledFeature.rgw && permissions.rgw.read">
- <a dropdownToggle
- class="dropdown-toggle"
- data-toggle="dropdown">
- <ng-container i18n>Object Gateway</ng-container>
- <span class="caret"></span>
- </a>
- <ul *dropdownMenu
- class="dropdown-menu">
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_rgw_daemons">
- <a i18n
- class="dropdown-item"
- routerLink="/rgw/daemon">Daemons</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_rgw_users">
- <a i18n
- class="dropdown-item"
- routerLink="/rgw/user">Users</a>
- </li>
- <li routerLinkActive="active"
- class="tc_submenuitem tc_submenuitem_rgw_buckets">
- <a i18n
- class="dropdown-item"
- routerLink="/rgw/bucket">Buckets</a>
- </li>
- </ul>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_log"
+ *ngIf="permissions.log.read">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/logs">Logs</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_prometheus"
+ *ngIf="prometheusConfigured && permissions.prometheus.read">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/alerts">Alerts</a>
+ </li>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_prometheus"
+ *ngIf="prometheusConfigured && permissions.prometheus.read">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/silence">Silences</a>
</li>
</ul>
- <!-- /.navbar-primary -->
+ </li>
+
+ <!-- Pools -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_pool"
+ *ngIf="permissions.pool.read">
+ <a class="nav-link"
+ i18n
+ routerLink="/pool">Pools</a>
+ </li>
+
+ <!-- Block -->
+ <li dropdown
+ routerLinkActive="active"
+ class="nav-item dropdown tc_menuitem_block"
+ *ngIf="permissions.rbdImage.read || permissions.rbdMirroring.read || permissions.iscsi.read">
+ <a dropdownToggle
+ class="nav-link dropdown-toggle"
+ data-toggle="dropdown"
+ [ngStyle]="blockHealthColor()">
+ <ng-container i18n>Block</ng-container>
+ </a>
- <ul class="nav navbar-nav navbar-utility">
- <li>
- <cd-language-selector class="oa-navbar"></cd-language-selector>
+ <ul *dropdownMenu
+ class="dropdown-menu">
+ <li routerLinkActive="active"
+ *ngIf="permissions.rbdImage.read">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/block/rbd">Images</a>
</li>
- <li>
- <cd-task-manager class="oa-navbar"></cd-task-manager>
+
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_block_mirroring"
+ *ngIf="permissions.rbdMirroring.read">
+ <a class="dropdown-item"
+ routerLink="/block/mirroring">
+ <ng-container i18n>Mirroring</ng-container>
+ <small *ngIf="summaryData?.rbd_mirroring?.warnings !== 0"
+ class="badge badge-warning">{{ summaryData?.rbd_mirroring?.warnings }}</small>
+ <small *ngIf="summaryData?.rbd_mirroring?.errors !== 0"
+ class="badge badge-danger">{{ summaryData?.rbd_mirroring?.errors }}</small>
+ </a>
</li>
- <li>
- <cd-notifications class="oa-navbar"></cd-notifications>
+
+ <li routerLinkActive="active"
+ *ngIf="permissions.iscsi.read">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/block/iscsi">iSCSI</a>
</li>
- <li>
- <cd-dashboard-help class="oa-navbar"></cd-dashboard-help>
+ </ul>
+ </li>
+
+ <!-- NFS -->
+ <li routerLinkActive="active"
+ class="item tc_menuitem_nfs"
+ *ngIf="permissions?.nfs?.read">
+ <a i18n
+ class="nav-link"
+ routerLink="/nfs">NFS</a>
+ </li>
+
+ <!-- Filesystem -->
+ <li routerLinkActive="active"
+ class="nav-item tc_menuitem_cephs"
+ *ngIf="permissions.cephfs.read">
+ <a i18n
+ class="nav-link"
+ routerLink="/cephfs">Filesystems</a>
+ </li>
+
+ <!-- Object Gateway -->
+ <li dropdown
+ routerLinkActive="active"
+ class="nav-item dropdown tc_menuitem_rgw"
+ *ngIf="permissions.rgw.read">
+ <a dropdownToggle
+ class="nav-link dropdown-toggle"
+ data-toggle="dropdown">
+ <ng-container i18n>Object Gateway</ng-container>
+ </a>
+ <ul *dropdownMenu
+ class="dropdown-menu">
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_rgw_daemons">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/rgw/daemon">Daemons</a>
</li>
- <li>
- <cd-administration class="oa-navbar"></cd-administration>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_rgw_users">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/rgw/user">Users</a>
</li>
- <li>
- <cd-identity class="oa-navbar"></cd-identity>
+ <li routerLinkActive="active"
+ class="tc_submenuitem tc_submenuitem_rgw_buckets">
+ <a i18n
+ class="dropdown-item"
+ routerLink="/rgw/bucket">Buckets</a>
</li>
</ul>
- <!-- /.navbar-utility -->
- </div>
- <!-- /.navbar-collapse -->
-</nav>
+ </li>
+</ng-template>
-@import '../../../../defaults';
+@import 'defaults';
/* Navbar */
-::ng-deep .navbar-main {
+::ng-deep .cd-navbar-top {
margin-bottom: 0;
background: $color-navbar-bg;
border: 0;
border-radius: 0;
- border-top: 4px solid $color-nav-top-bar;
- font-size: 1.2em;
- .navbar-header {
- display: flex;
- float: none;
- }
+ .cd-navbar-brand {
+ border-top: 4px solid $color-nav-top-bar;
- .navbar-brand,
- .navbar-brand:hover {
- color: $color-navbar-brand;
- height: auto;
- margin: 15px 0 15px 20px;
- padding: 0;
- -webkit-align-self: flex-start;
- align-self: flex-start;
- }
+ .navbar-brand,
+ .navbar-brand:hover {
+ color: $color-navbar-brand;
+ height: auto;
+ padding: 0;
+ }
- .navbar-brand > img {
- height: 25px;
- }
+ .navbar-brand > img {
+ height: 25px;
+ }
- .navbar-toggle {
- margin-left: auto;
- border: 0;
- }
+ .navbar-toggler {
+ border: 0;
- .navbar-toggle:focus,
- .navbar-toggle:hover {
- background-color: transparent;
- outline: 0;
- }
+ &:focus,
+ &:hover {
+ outline: 0;
+ }
- .navbar-toggle .icon-bar {
- background-color: $color-nav-toggle-bar;
- }
+ .fa-navicon {
+ color: $color-nav-toggle-bar;
+ }
+ }
- .navbar-toggle:focus .icon-bar,
- .navbar-toggle:hover .icon-bar {
- -webkit-box-shadow: 0 0 3px $color-nav-toggle-shadow;
- box-shadow: 0 0 3px $color-nav-toggle-shadow;
- }
+ .navbar-collapse {
+ padding: 0;
+ }
- .navbar-collapse {
- padding: 0;
- }
+ .cd-navbar-utility > .active > a {
+ color: $color-nav-links;
+ background-color: $color-nav-links-hover;
+ }
- .navbar-nav > li > .oa-navbar > [dropdown] > ul > li > .dropdown-item {
- font-size: 12px;
+ .cd-navbar-utility > li > .open > a,
+ .cd-navbar-utility > li > .open > a:focus,
+ .cd-navbar-utility > li > .open > a:hover {
+ color: $color-nav-links;
+ border-color: transparent;
+ background-color: transparent;
+ }
}
- .navbar-nav > li > .oa-navbar > [dropdown] > a,
- .navbar-nav > li > .oa-navbar > a,
+ .navbar-nav > li > .cd-navbar > [dropdown] > a,
+ .navbar-nav > li > .cd-navbar > a,
.navbar-nav > li > a {
color: $color-nav-links;
line-height: 1;
- padding: 10px 18px;
+ padding: 10px 18px !important;
position: relative;
display: block;
text-decoration: none;
}
- .navbar-nav > li > .oa-navbar > [dropdown] > a:focus,
- .navbar-nav > li > .oa-navbar > [dropdown] > a:hover,
- .navbar-nav > li > .oa-navbar > a:focus,
- .navbar-nav > li > .oa-navbar > a:hover,
- .navbar-nav > li > a:focus,
- .navbar-nav > li > a:hover {
+ .navbar-nav .nav-link,
+ .navbar-nav .nav-link:hover {
color: $color-nav-links;
}
- .navbar-nav > li > .oa-navbar > [dropdown] > a:hover,
- .navbar-nav > li > .oa-navbar > [dropdown].open > a,
- .navbar-nav > li > .oa-navbar > a:hover,
- .navbar-nav > li > a:hover {
+ .navbar-nav > li > .cd-navbar > [dropdown] > a:hover,
+ .navbar-nav > li > .cd-navbar > [dropdown].open > a,
+ .navbar-nav > li > .cd-navbar > a:hover,
+ .navbar-nav > li > a:hover,
+ .navbar-nav > li:hover {
background-color: $color-nav-links-hover;
}
- .navbar-nav > li a.dropdown-toggle span.caret {
- margin-left: 5px;
- }
-
- .navbar-nav > .open > .oa-navbar > [dropdown] > a,
- .navbar-nav > .open > .oa-navbar > [dropdown] > a:hover,
- .navbar-nav > .open > .oa-navbar > a,
- .navbar-nav > .open > .oa-navbar > a:focus,
- .navbar-nav > .open > .oa-navbar > a:hover,
- .navbar-nav > .open > .oa-navbar > li > a:focus,
+ .navbar-nav > .open > .cd-navbar > [dropdown] > a,
+ .navbar-nav > .open > .cd-navbar > [dropdown] > a:hover,
+ .navbar-nav > .open > .cd-navbar > a,
+ .navbar-nav > .open > .cd-navbar > a:focus,
+ .navbar-nav > .open > .cd-navbar > a:hover,
+ .navbar-nav > .open > .cd-navbar > li > a:focus,
.navbar-nav > .open > a,
.navbar-nav > .open > a:focus,
.navbar-nav > .open > a:hover {
background-color: transparent;
}
- .navbar-primary > li > a {
- border: 0;
+ .cd-navbar-primary {
+ font-size: 1.2em;
}
- .navbar-primary > .active > a,
- .navbar-primary > .active > a:focus,
- .navbar-primary > .active > a:hover {
- color: $color-nav-links;
- background-color: $color-nav-links-hover;
+ .cd-navbar-primary > li > a {
border: 0;
}
- .navbar-utility .fa,
- .navbar-utility a {
- font-size: 1.1em;
- }
-
- .navbar-utility > .active > a {
+ .cd-navbar-primary > .active > a,
+ .cd-navbar-primary > .active > a:focus,
+ .cd-navbar-primary > .active > a:hover {
color: $color-nav-links;
background-color: $color-nav-links-hover;
+ border: 0;
}
- .navbar-utility > li > .open > a,
- .navbar-utility > li > .open > a:focus,
- .navbar-utility > li > .open > a:hover {
- color: $color-nav-links;
- border-color: transparent;
- background-color: transparent;
- }
- @media (min-width: $screen-sm-min) {
+ @media (min-width: $screen-md-min) {
.navbar-primary > li > a {
border-bottom: 4px solid transparent;
}
- .navbar-primary > .active > a,
- .navbar-primary > .active > a:focus,
- .navbar-primary > .active > a:hover {
+ .cd-navbar-primary > .active > a,
+ .cd-navbar-primary > .active > a:focus,
+ .cd-navbar-primary > .active > a:hover {
background-color: transparent;
border-bottom: 4px solid $color-nav-bottom-bar;
}
- .navbar-utility {
+ .cd-navbar-utility {
border-bottom: 0;
- font-size: 11px;
position: absolute;
right: 0;
top: 0;
+ font-size: 1.1rem;
}
}
- @media (max-width: $screen-xs-max) {
+
+ @media (max-width: $screen-sm-max) {
.navbar-nav {
margin: 0;
.fa {
margin-right: 0.5em;
}
- }
-
- .navbar-collapse,
- .navbar-form {
- border-color: $color-nav-collapse-border;
- }
-
- .navbar-collapse {
- padding: 0;
- }
- .navbar-nav .open .dropdown-menu {
- padding-top: 0;
- padding-bottom: 0;
- background-color: $color-nav-open-bg;
- }
+ .open .dropdown-menu {
+ border: 0;
+ padding-top: 0;
+ padding-bottom: 0;
+ background-color: $color-nav-open-bg;
+ }
- .navbar-nav .open .dropdown-menu .dropdown-header,
- .navbar-nav .open .dropdown-menu > li > a {
- padding: 5px 15px 5px 35px;
- }
+ .open .dropdown-menu > li > a {
+ padding: 5px 15px 5px 35px;
+ color: $color-nav-links;
+ }
- .navbar-nav .open .dropdown-menu > li > a {
- color: $color-nav-links;
- }
+ .open .dropdown-menu > .active > a {
+ background-color: $color-nav-active-link-bg;
+ }
- .navbar-nav .open .dropdown-menu > .active > a {
- color: $color-nav-links;
- background-color: $color-nav-active-link-bg;
+ & > li > a:hover {
+ background-color: $color-nav-active-link-bg;
+ }
}
- .navbar-nav > li > a:hover {
- background-color: $color-nav-active-link-bg;
+ .cd-navbar-primary {
+ margin-top: 5px;
+ border-top: 1px solid $color-nav-border-top-collapse;
}
- .navbar-utility {
+ .cd-navbar-utility {
border-top: 1px solid $color-nav-border-top-collapse;
+ font-size: 1.2em;
- a {
- font-size: 1em;
+ .btn-group {
+ display: block;
}
}
- .navbar-primary > .active > a,
- .navbar-primary > .active > a:focus,
- .navbar-primary > .active > a:hover {
+ .cd-navbar-primary > .active > a,
+ .cd-navbar-primary > .active > a:focus,
+ .cd-navbar-primary > .active > a:hover {
background-color: $color-nav-active-link-bg;
}
}
<ng-template #notificationsTpl>
<div *ngIf="notifications.length > 0">
- <button type="button" class="btn btn-default btn-sm btn-block" (click)="removeAll()">
+ <button type="button" class="btn btn-light btn-block" (click)="removeAll()">
<i [ngClass]="[icons.trash]" aria-hidden="true"></i>
<ng-container i18n>Remove all</ng-container>
<ng-template #emptyTpl>
<div *ngIf="notifications.length === 0">
- <div class="message">
- There are no notifications.
- </div>
+ <div class="message"
+ i18n>There are no notifications.</div>
</div>
</ng-template>
outsideClick="true"
i18n-title
title="Recent Notifications">
- <i [ngClass]="[icons.bell, icons.width]"></i>
+ <i [ngClass]="[icons.bell]"></i>
<span i18n
- class="visible-xs-inline-block">Recent Notifications</span>
+ class="d-md-none">Recent Notifications</span>
</a>
-@import '../../../../styles/popover.scss';
+@import 'popover.scss';
outsideClick="true"
i18n-title
title="Background Tasks">
- <i [ngClass]="[icon,icons.width]"></i>
+ <i [ngClass]="[icon]"></i>
<span i18n
- class="visible-xs-inline-block">Background Tasks</span>
+ class="d-md-none">Background Tasks</span>
<span *ngIf="executingTasks.length > 0"> ({{ executingTasks.length }})</span>
</a>
it('should get an empty hour glass with only finished tasks', () => {
component._setIcon(0);
- expect(component.icon).toBe('fa-hourglass-o');
+ expect(component.icon).toBe('fa fa-hourglass-o');
});
it('should get a nearly empty hour glass with executing tasks', () => {
component._setIcon(10);
- expect(component.icon).toBe('fa-hourglass-start');
+ expect(component.icon).toBe('fa fa-hourglass-start');
});
});
_setIcon(executingTasks: number) {
const iconSuffix = ['o', 'start', 'half', 'end']; // TODO: Use all suffixes
const iconIndex = executingTasks > 0 ? 1 : 0;
- this.icon = 'fa-hourglass-' + iconSuffix[iconIndex];
+ this.icon = [Icons.filledHourglass, iconSuffix[iconIndex]].join('-');
}
}
<div class="col-md-12 text-center">
<h1 i18n>Sorry, we could not find what you were looking for</h1>
- <img class="img-responsive center-block img-rounded"
+ <img class="img-fluid mx-auto rounded"
src="/assets/1280px-Nautilus_Octopus.jpg">
<span>
"<a href="https://www.flickr.com/photos/146401137@N06/40335060661">Nautilus Octopus</a>" by Jin Kemoole is licensed under
-<button class="btn btn-sm btn-default tc_backButton"
+<button class="btn btn btn-light tc_backButton"
(click)="back()"
type="button">
{{ name }}
<div [formGroup]="optionsFormGroup">
<div *ngFor="let option of options; let last = last">
- <div class="form-group"
- [ngClass]="{'has-error': optionsForm.showError(option.name, optionsFormDir)}"
+ <div class="form-group row pt-2"
*ngIf="option.type === 'bool'">
- <label class="col-sm-6 control-label"
+ <label class="control-label col-6"
[for]="option.name">
- {{ option.text }}
+ <b>{{ option.text }}</b>
<br>
<span class="text-muted">
{{ option.desc }}
{{ option.long_desc }}</cd-helper>
</span>
</label>
- <div class="col-sm-6 checkbox-primary checkbox">
- <input type="checkbox"
- [id]="option.name"
- [formControlName]="option.name">
- <label></label>
+
+ <div class="col-6">
+ <div class="custom-control custom-checkbox">
+ <input class="custom-control-input"
+ type="checkbox"
+ [id]="option.name"
+ [formControlName]="option.name">
+ <label class="custom-control-label"
+ [for]="option.name"></label>
+ </div>
</div>
</div>
- <div class="form-group"
- [ngClass]="{'has-error': optionsForm.showError(option.name, optionsFormDir)}"
+
+ <div class="form-group row pt-2"
*ngIf="option.type !== 'bool'">
- <label class="col-sm-6 control-label"
+ <label class="col-6 control-label"
[for]="option.name">{{ option.text }}
<br>
<span class="text-muted">
{{ option.long_desc }}</cd-helper>
</span>
</label>
- <div class="col-sm-6">
+ <div class="col-6">
<div class="input-group">
<input class="form-control"
[type]="option.additionalTypeInfo.inputType"
[placeholder]="option.additionalTypeInfo.humanReadable"
[formControlName]="option.name"
[step]="getStep(option.type, optionsForm.getValue(option.name))">
- <span class="input-group-btn"
- *ngIf="optionsFormShowReset">
- <button class="btn btn-default"
+ <div class="input-group-append"
+ *ngIf="optionsFormShowReset">
+ <button class="btn btn-light"
type="button"
data-toggle="button"
title="Remove the custom configuration value. The default configuration will be inherited and used instead."
<i [ngClass]="[icons.erase]"
aria-hidden="true"></i>
</button>
- </span>
+ </div>
</div>
- <span class="help-block"
+ <span class="invalid-feedback"
*ngIf="optionsForm.showError(option.name, optionsFormDir, 'pattern')">
{{ option.additionalTypeInfo.patternHelpText }}</span>
- <span class="help-block"
+ <span class="invalid-feedback"
*ngIf="optionsForm.showError(option.name, optionsFormDir, 'invalidUuid')">
{{ option.additionalTypeInfo.patternHelpText }}</span>
- <span class="help-block"
+ <span class="invalid-feedback"
*ngIf="optionsForm.showError(option.name, optionsFormDir, 'max')"
i18n>The entered value is too high! It must not be greater than {{ option.maxValue }}.</span>
- <span class="help-block"
+ <span class="invalid-feedback"
*ngIf="optionsForm.showError(option.name, optionsFormDir, 'min')"
i18n>The entered value is too low! It must not be lower than {{ option.minValue }}.</span>
</div>
</div>
- <hr *ngIf="!last">
+ <hr *ngIf="!last"
+ class="my-2">
</div>
</div>
-hr {
- margin-top: 5px;
- margin-bottom: 5px;
-}
-
-.control-label {
- text-align: left;
-}
-
-.checkbox-primary {
+.custom-checkbox {
+ label,
input {
- width: 23px;
- height: 15px;
- margin-left: 0;
cursor: pointer;
}
- label {
- &:before,
- &:after {
- margin-left: 0;
- }
- cursor: auto;
- }
-}
-
-.form-group {
- .col-sm-6 {
- padding-top: 7px;
- }
}
<ng-container class="modal-title">{{ titleText }}</ng-container>
<ng-container class="modal-content">
<form name="confirmationForm"
- class="form-horizontal"
#formDir="ngForm"
[formGroup]="confirmationForm"
novalidate>
<div class="modal-body">
<ng-container *ngTemplateOutlet="bodyTemplate; context: bodyContext"></ng-container>
<div class="question">
- <p i18n>Are you sure that you want to {{ actionDescription | lowercase }} the selected {{ itemDescription }}?</p>
+ <p i18n>Are you sure that you want to
+ {{ actionDescription | lowercase }} the selected {{ itemDescription }}?</p>
<div class="form-group"
- [ngClass]="{'has-error': deletionForm.showError('confirmation', formDir)}">
- <div class="checkbox checkbox-primary">
- <input type="checkbox"
+ [ngClass]="{':invalid': deletionForm.showError('confirmation', formDir)}">
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ type="checkbox"
name="confirmation"
id="confirmation"
formControlName="confirmation"
autofocus>
- <label i18n
+ <label class="form-check-label"
+ i18n
for="confirmation">Yes, I am sure.</label>
</div>
</div>
font-weight: bold;
margin-top: 1em;
}
-.modal-body .question .checkbox {
+.modal-body .question .form-check {
padding-top: 7px;
}
@Component({
template: `
- <button type="button" class="btn btn-sm btn-primary" (click)="openCtrlDriven()">
- <i class="fa fa-fw fa-times"></i>Deletion Ctrl-Test
+ <button type="button" class="btn btn-secondary" (click)="openCtrlDriven()">
+ <i class="fa fa-times"></i>Deletion Ctrl-Test
<ng-template #ctrlDescription>
The spinner is handled by the controller if you have use the modal as ViewChild in order to
use it's functions to stop the spinner or close the dialog.
</ng-template>
</button>
- <button type="button" class="btn btn-sm btn-primary" (click)="openModalDriven()">
- <i class="fa fa-fw fa-times"></i>Deletion Modal-Test
+ <button type="button" class="btn btn-secondary" (click)="openModalDriven()">
+ <i class="fa fa-times"></i>Deletion Modal-Test
<ng-template #modalDescription>
The spinner is handled by the modal if your given deletion function returns a Observable.
</ng-template>
<div class="button-group text-right"
*ngIf="backAction.observers.length > 0">
- <button class="btn btn-sm btn-default tc_backButton"
+ <button class="btn btn-light tc_backButton"
type="button"
(click)="backAction.emit()"
autofocus
<cd-info-panel *ngIf="!grafanaExist"
i18n>Please consult the
- <a href="{{ docsUrl }}" target="_blank">documentation</a> on how to
+ <a href="{{ docsUrl }}"
+ target="_blank">documentation</a> on how to
configure and enable the monitoring functionality.</cd-info-panel>
<cd-info-panel *ngIf="!dashboardExist"
i18n>Grafana Dashboard doesn't exist. Please refer to
- <a href="{{ docsUrl }}" target="_blank">documentation</a> on how to
+ <a href="{{ docsUrl }}"
+ target="_blank">documentation</a> on how to
add dashboards to Grafana.</cd-info-panel>
-<div class="row"
- *ngIf="grafanaExist && dashboardExist">
- <div class="col-md-12 timepicker">
- <label class="control-label col-sm-1"
- for="timepicker-control">
- <ng-container i18n>Grafana Time Picker</ng-container>
- </label>
- <div class="col-sm-9">
- <select id="timepicker"
- name="timepicker-control"
- class="form-control "
- [(ngModel)]="time"
- (ngModelChange)="onTimepickerChange($event)">
- <option *ngFor="let key of grafanaTimes"
- [ngValue]="key.value">{{ key.name }}
- </option>
- </select>
+<ng-container *ngIf="grafanaExist && dashboardExist">
+ <div class="row">
+ <div class="col-12">
+ <div class="form-inline timepicker">
+ <label for="timepicker"
+ class="ml-1 my-1"
+ i18n>Grafana Time Picker</label>
+
+ <select id="timepicker"
+ name="timepicker"
+ class="custom-select my-1 mx-3"
+ [(ngModel)]="time"
+ (ngModelChange)="onTimepickerChange($event)">
+ <option *ngFor="let key of grafanaTimes"
+ [ngValue]="key.value">{{ key.name }}
+ </option>
+ </select>
+
+ <button class="btn btn-light my-1"
+ i18n-title
+ title="Reset Settings"
+ (click)="reset()">
+ <i [ngClass]="[icons.undo]"></i>
+ </button>
+ </div>
</div>
- <button class="btn btn-sm"
- i18n-title
- title="Reset Settings"
- (click)="reset()">
- <i [ngClass]="[icons.undo]"></i>
- </button>
- <br>
</div>
- <div class="col-md-12">
- <div class="grafana-container">
- <iframe #iframe
- id="iframe"
- [src]="grafanaSrc"
- class="grafana"
- [ngClass]="panelStyle"
- frameborder="0"
- scrolling="no">
- </iframe>
+
+ <div class="row">
+ <div class="col-12">
+ <div class="grafana-container">
+ <iframe #iframe
+ id="iframe"
+ [src]="grafanaSrc"
+ class="grafana"
+ [ngClass]="panelStyle"
+ frameborder="0"
+ scrolling="no">
+ </iframe>
+ </div>
</div>
</div>
-</div>
+</ng-container>
}
.timepicker {
- select {
- display: inline-block;
- }
-
label {
- font-size: 1.05em;
- padding: 5px !important;
- }
-}
-
-button {
- margin-bottom: 10px;
- margin-left: 10px;
- float: right;
- i {
- font-size: 14px;
- padding: 2px;
+ font-weight: 700;
}
}
-@import '../../../../defaults';
+@import 'defaults';
i {
color: $color-helper-bg;
<div dropdown\r
+ class="btn-group"\r
*ngIf="isDropdown">\r
<a dropdownToggle\r
class="dropdown-toggle"\r
i18n-title\r
title="Select a Language">\r
{{ supportedLanguages[selectedLanguage] }}\r
- <span class="caret"></span>\r
</a>\r
<ul *dropdownMenu\r
class="dropdown-menu dropdown-menu-right">\r
<alert type="info">
<strong>
- <i [ngClass]="[icons.spinner, icons.spin, icons.width]"
+ <i [ngClass]="[icons.spinner, icons.spin]"
aria-hidden="true"></i>
</strong>
<ng-content></ng-content>
<div class="modal-header">
- <h4 class="modal-title pull-left">
+ <h4 class="modal-title float-left">
<ng-content select=".modal-title"></ng-content>
</h4>
<button type="button"
- class="close pull-right"
+ class="close float-right"
aria-label="Close"
(click)="close()">
<span aria-hidden="true">×</span>
-@import '../../../../defaults';
+@import 'defaults';
.modal-header {
@include hf;
<div class="row">
- <div class="col-xs-5 col-sm-2 refresh-selector">
- <label class="control-label col-xs-5 col-sm-5"
- for="refreshInterval">
- <span i18n>Refresh</span>
- </label>
- <div class="col-xs-7 col-sm-7">
- <select id="refreshInterval"
- name="refreshInterval"
- class="form-control"
+ <div class="col-12">
+ <div class="float-right d-inline-flex">
+ <label for="refreshInterval"
+ class="m-2"
+ i18n>Refresh</label>
+ <select id="refreshInterval"
+ name="refreshInterval"
+ class="form-control"
(change)="changeRefreshInterval($event.target.value)"
[(ngModel)]="selectedInterval">
- <option *ngFor="let key of intervalKeys"
+ <option *ngFor="let key of intervalKeys"
[value]="intervalList[key]">{{ key }}</option>
</select>
</div>
</div>
-</div>
\ No newline at end of file
+</div>
-.refresh-selector {
- padding: 0;
- float: right;
- margin-right: 60px;
-
- * {
- padding: 0;
- box-sizing: border-box;
- }
-
- label {
- padding: 10px 10px 0 0;
- text-align: right;
- margin: 0;
- }
-
- @media (min-width: 500px) and (max-width: 767px) {
- width: 24vw;
- }
- @media (min-width: 1200px) {
- width: 12vw;
- }
- @media (min-width: 1400px) {
- width: 10vw;
- }
-}
[selectionLimit]="selectionLimit"
[customBadges]="customBadges"
[customBadgeValidators]="customBadgeValidators"
- elemClass="margin-right-sm select-menu-edit"
+ elemClass="mr-2 select-menu-edit"
(selection)="selection.emit($event)">
- <i [ngClass]="[icons.edit, icons.width]"></i>
+ <i [ngClass]="[icons.edit]"></i>
</cd-select>
<span *ngFor="let dataItem of data">
- <span class="badge badge-pill badge-primary margin-right-sm">
- <span class="margin-right-sm">{{ dataItem }}</span>
+ <span class="badge badge-pill badge-dark mr-2">
+ <span class="mr-2">{{ dataItem }}</span>
<a class="badge-remove"
(click)="cdSelect.removeItem(dataItem)">
<i [ngClass]="[icons.destroy]"
-@import '../../../../defaults';
+@import 'defaults';
-::ng-deep .select-menu-edit {
- margin-left: -20px;
-}
.badge-remove {
color: $color-solid-white;
}
+
+i.fa-pencil {
+ font-size: 1.1rem;
+}
#formDir="ngForm"
[formGroup]="form"
novalidate>
- <div [ngClass]="{'has-error': form.showError('filter', formDir)}">
+ <div [ngClass]="{':invalid': form.showError('filter', formDir)}">
<input type="text"
formControlName="filter"
i18n-placeholder
(keyup)="$event.keyCode == 13 ? selectOption() : updateFilter()"
class="form-control text-center" />
<ng-container *ngFor="let error of Object.keys(messages.customValidations)">
- <span class="help-block text-center"
+ <span class="form-text text-muted text-center"
*ngIf="form.showError('filter', formDir) && filter.hasError(error)">
{{ messages.customValidations[error] }}
</span>
{{ option.name }}
<ng-container *ngIf="option.description">
<br>
- <small class="text-muted">
+ <small class="form-text text-muted">
{{ option.description }}
</small>
</ng-container>
{{ messages.add }} '{{ filter.value }}'
</div>
</div>
- <div class="has-warning"
+ <div class=":invalid"
*ngIf="data.length === selectionLimit">
- <span class="help-block text-center text-warning"
+ <span class="form-text text-muted text-center text-warning"
[tooltip]="messages.selectionLimit.tooltip"
*ngIf="data.length === selectionLimit">
{{ messages.selectionLimit.text }}
placement="bottom"
container="body"
outsideClick="true"
- *ngIf="options.length > 0">
+ *ngIf="options.length > 0"
+ class="float-left">
<ng-content></ng-content>
</a>
-<span class="text-muted"
+
+<span class="form-text text-muted float-left"
*ngIf="data.length === 0 && options.length > 0">
{{ messages.empty }}
</span>
-<span class="text-muted"
+
+<span class="form-text text-muted float-left"
*ngIf="options.length === 0">
{{ messages.noOptions }}
</span>
-@import '../../../../defaults';
+@import 'defaults';
.select-menu-item {
display: block;
<button [type]="type"
- class="btn btn-sm btn-primary tc_submitButton"
+ class="btn btn-secondary tc_submitButton"
[disabled]="loading || disabled"
(click)="submit($event)">
<ng-content></ng-content>
<span *ngIf="loading">
- <i [ngClass]="[icons.spinner, icons.spin, icons.width]"></i>
+ <i [ngClass]="[icons.spinner, icons.spin]"></i>
</span>
</button>
</table>
</ng-template>
-<div class="progress oaprogress"
+<div class="progress"
data-placement="left"
[tooltip]="usageTooltipTpl">
- <div class="progress-bar progress-bar-info"
+ <div class="progress-bar bg-info"
role="progressbar"
[style.width]="usedPercentage + '%'">
<span>{{ usedPercentage }}%</span>
</div>
- <div class="progress-bar progress-bar-freespace"
+ <div class="progress-bar bg-freespace"
role="progressbar"
[style.width]="freePercentage + '%'">
</div>
+@import 'defaults';
+
+.bg-info {
+ background-color: $color-progress-bar-info-bg !important;
+}
+
+.bg-freespace {
+ background-color: $color-progress-bar-freespace-bg !important;
+}
+
+.progress {
+ height: 20px;
+ position: relative;
+ margin-bottom: 0;
+
+ div.progress-bar {
+ position: static;
+ }
+
+ span {
+ position: absolute;
+ display: block;
+ width: 100%;
+ color: $color-progress-text;
+ font-weight: normal;
+ }
+}
dropdown>
<ng-container *ngIf="getCurrentButton() as action">
<button type="button"
- class="btn btn-sm btn-{{btnColor}}"
+ class="btn btn-{{btnColor}}"
[ngClass]="{'disabled': disableSelectionAction(action)}"
(click)="useClickAction(action)"
[routerLink]="useRouterLink(action)">
- <i [ngClass]="[action.icon, icons.width]"></i><span>{{ action.name }}</span>
+ <i [ngClass]="[action.icon]"></i><span>{{ action.name }}</span>
</button>
</ng-container>
<button type="button"
dropdownToggle
*ngIf="showDropDownActions()"
- class="btn btn-sm btn-{{btnColor}} dropdown-toggle dropdown-toggle-split">
+ class="btn btn-{{btnColor}} dropdown-toggle dropdown-toggle-split">
<ng-container *ngIf="dropDownOnly">{{ dropDownOnly }} </ng-container>
- <span class="caret"></span>
<span *ngIf="!dropDownOnly"
class="sr-only"></span>
</button>
<ng-container *ngFor="let action of dropDownActions">
<li role="menuitem"
class="{{ toClassName(action['name']) }}"
- [ngClass]="{'disabled': disableSelectionAction(action)}"
data-toggle="tooltip" title="{{ useDisableDesc(action) }}">
<a class="dropdown-item"
(click)="useClickAction(action)"
- [routerLink]="useRouterLink(action)">
- <i [ngClass]="[action.icon, icons.width]"></i><span>{{ action.name }}</span>
+ [routerLink]="useRouterLink(action)"
+ [ngClass]="{'disabled': disableSelectionAction(action)}">
+ <i [ngClass]="[action.icon]"></i><span>{{ action.name }}</span>
</a>
</li>
</ng-container>
+@import '~bootstrap/scss/bootstrap-grid';
+
.dropdown-menu > .disabled > a {
pointer-events: auto;
cursor: default !important;
}
+
+::ng-deep .btn-toolbar .btn-group {
+ @extend .mr-1;
+}
@Input()
tableActions: CdTableAction[];
@Input()
- btnColor = 'primary';
+ btnColor = 'secondary';
// Use this if you just want to display a drop down button,
// labeled with the given text, with all actions in it.
import { RouterTestingModule } from '@angular/router/testing';
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
+import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { configureTestBed } from '../../../../testing/unit-test-helper';
import { ComponentsModule } from '../../components/components.module';
configureTestBed({
declarations: [TableComponent, TableKeyValueComponent],
- imports: [FormsModule, NgxDatatableModule, ComponentsModule, RouterTestingModule]
+ imports: [
+ FormsModule,
+ NgxDatatableModule,
+ ComponentsModule,
+ RouterTestingModule,
+ BsDropdownModule.forRoot()
+ ]
});
beforeEach(() => {
i18n>Failed to load data.</cd-error-panel>
<div class="dataTables_wrapper">
- <div class="dataTables_header clearfix form-inline"
+ <div class="dataTables_header clearfix"
*ngIf="toolHeader">
<!-- actions -->
- <div class="oadatatableactions">
+ <div class="cd-datatable-actions">
<ng-content select=".table-actions"></ng-content>
</div>
<!-- end actions -->
<!-- search -->
<div class="input-group">
- <span class="input-group-addon">
+ <span class="input-group-prepend">
+ <span class="input-group-text">
<i [ngClass]="[icons.search]"></i>
+ </span>
</span>
<input class="form-control"
type="text"
[(ngModel)]="search"
(keyup)="updateFilter()">
- <span class="input-group-btn">
+ <div class="input-group-append">
<button type="button"
- class="btn btn-default clear-input tc_clearInputBtn"
+ class="btn btn-light"
(click)="updateFilter(true)">
<i class="icon-prepend {{ icons.destroy }}"></i>
</button>
- </span>
+ </div>
</div>
<!-- end search -->
<!-- show hide columns -->
<div class="widget-toolbar">
<div dropdown
+ [autoClose]="false"
class="dropdown tc_menuitem tc_menuitem_cluster">
<a dropdownToggle
- class="btn btn-sm btn-default dropdown-toggle tc_columnBtn"
+ class="btn btn-light dropdown-toggle tc_columnBtn"
data-toggle="dropdown">
<i [ngClass]="[icons.large, icons.table]"></i>
</a>
<ul *dropdownMenu
- class="dropdown-menu">
+ class="dropdown-menu px-3">
<li *ngFor="let column of columns">
- <label>
- <input type="checkbox"
+
+ <div class="form-check abc-checkbox abc-checkbox-primary">
+ <input class="form-check-input"
+ type="checkbox"
(change)="toggleColumn($event)"
[name]="column.prop"
+ [id]="column.prop"
[checked]="!column.isHidden">
- <span>{{ column.name }}</span>
- </label>
+ <label class="form-check-label"
+ [for]="column.prop">{{ column.name }}</label>
+ </div>
</li>
</ul>
</div>
<!-- refresh button -->
<div class="widget-toolbar tc_refreshBtn"
*ngIf="fetchData.observers.length > 0">
- <a (click)="refreshBtn()">
+
+ <button type="button"
+ class="btn btn-light"
+ (click)="refreshBtn()">
<i [ngClass]="[icons.large, icons.refresh]"
[class.fa-spin]="updating || loadingIndicator"></i>
- </a>
+ </button>
</div>
<!-- end refresh button -->
</div>
<ngx-datatable #table
- class="bootstrap oadatatable"
+ class="bootstrap cd-datatable"
[cssClasses]="paginationClasses"
[selectionType]="selectionType"
[selected]="selection.selected"
<ng-template #checkIconTpl
let-value="value">
- <i [ngClass]="[icons.check, icons.width]"
+ <i [ngClass]="[icons.check]"
[hidden]="!value"></i>
</ng-template>
<ng-template #executingTpl
let-row="row"
let-value="value">
- <i [ngClass]="[icons.spinner, icons.width, icons.spin]"
+ <i [ngClass]="[icons.spinner, icons.spin]"
*ngIf="row.cdExecuting"></i>
{{ value }}
<span *ngIf="row.cdExecuting"
-@import '../../../../defaults';
+@import 'styles';
.dataTables_wrapper {
margin-bottom: 25px;
display: inline-block;
vertical-align: middle;
}
+
.widget-toolbar {
- display: inline-block;
float: right;
- width: auto;
- height: 30px;
- line-height: 28px;
- position: relative;
+ // width: auto;
+ // height: 30px;
+ // line-height: 28px;
+ // position: relative;
border-left: 1px solid $color-table-seperator-border;
- cursor: pointer;
+ // cursor: pointer;
padding: 0 8px;
- text-align: center;
+ // text-align: center;
+
+ .form-check {
+ padding-left: 0;
+ }
}
+
.dropdown-menu {
white-space: nowrap;
& > li {
}
}
}
- th.oadatatablecheckbox {
- width: 16px;
- }
.dataTables_length > input {
line-height: 25px;
text-align: right;
border-bottom: none;
padding: 5px;
position: relative;
- .oadatatableactions {
+ .cd-datatable-actions {
float: left;
}
::ng-deep .table-filters {
.form-control {
height: 30px;
}
- .clear-input {
- height: 30px;
- i {
- vertical-align: text-top;
- }
- }
}
.input-group.dataTables_paginate {
width: 8%;
}
}
-::ng-deep .oadatatable {
+::ng-deep .cd-datatable {
border: 1px solid $color-table-header-border;
margin-bottom: 0;
max-width: none !important;
+
.progress-linear {
display: block;
position: relative;
height: 5px;
padding: 0;
margin: 0;
+
.container {
background-color: $color-table-active-row;
+
.bar {
left: 0;
height: 100%;
overflow: hidden;
background-color: $color-table-active-row;
}
+
.bar:before {
display: block;
position: absolute;
}
}
}
+
.datatable-header {
background-clip: padding-box;
background-color: $color-table-datatable-header;
);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffafafa', endColorstr='#ffededed', GradientType=0);
+
.sort-asc,
.sort-desc {
color: $color-table-sort;
}
+
.datatable-header-cell {
@include table-cell;
+
text-align: left;
font-weight: bold;
+
.datatable-header-cell-label {
&:after {
font-family: ForkAwesome;
width: 12px;
}
}
+
&.sortable {
.datatable-header-cell-label:after {
content: ' \f0dc';
}
+
&.sort-active {
&.sort-asc .datatable-header-cell-label:after {
content: ' \f160';
}
+
&.sort-desc .datatable-header-cell-label:after {
content: ' \f161';
}
}
}
+
&:first-child {
border-left: none;
}
}
}
.datatable-body {
+ margin-bottom: -6px;
+
.empty-row {
background-color: $color-table-empty-row;
text-align: center;
padding-bottom: 5px;
}
.datatable-body-row {
- .label {
- font-size: 0.9em;
- }
&.clickable:hover .datatable-row-group {
background-color: $color-table-hover-row;
transition-property: background;
}
}
.datatable-footer {
+ @extend .p-2;
+
.selected-count,
.page-count {
font-style: italic;
padding-left: 5px;
}
- .datatable-pager .pager {
- margin-right: 5px !important;
- & li:not(:first-child) {
- /** Add space between buttons */
- margin-left: 3px;
- }
- & li > a,
- & li > span {
- border-radius: 3px;
- }
- .pages {
- & > a,
- & > span {
- display: inline-block;
- padding: 5px 10px;
- margin-bottom: 5px;
- border: none;
- }
- a:hover {
- background-color: $color-table-active-row;
- }
- &.active > a {
- background-color: $color-table-active-row-hover;
+ .datatable-pager {
+ // .pager
+ ul {
+ @extend .pagination;
+
+ li {
+ @extend .page-item;
+
+ a {
+ @extend .page-link;
+ }
}
}
}
import { NgxDatatableModule } from '@swimlane/ngx-datatable';
import * as _ from 'lodash';
+import { BsDropdownModule } from 'ngx-bootstrap/dropdown';
import { configureTestBed } from '../../../../testing/unit-test-helper';
import { ComponentsModule } from '../../components/components.module';
configureTestBed({
declarations: [TableComponent],
- imports: [NgxDatatableModule, FormsModule, ComponentsModule, RouterTestingModule]
+ imports: [
+ NgxDatatableModule,
+ FormsModule,
+ ComponentsModule,
+ RouterTestingModule,
+ BsDropdownModule.forRoot()
+ ]
});
beforeEach(() => {
describe('useCustomClass', () => {
beforeEach(() => {
component.customCss = {
- 'label label-danger': 'active',
+ 'badge badge-danger': 'active',
'secret secret-number': 123.456,
- 'btn btn-sm': (v) => _.isString(v) && v.startsWith('http'),
+ btn: (v) => _.isString(v) && v.startsWith('http'),
secure: (v) => _.isString(v) && v.startsWith('https')
};
});
});
it('should match a string and return the corresponding class', () => {
- expect(component.useCustomClass('active')).toBe('label label-danger');
+ expect(component.useCustomClass('active')).toBe('badge badge-danger');
});
it('should match a number and return the corresponding class', () => {
});
it('should match against a function and return the corresponding class', () => {
- expect(component.useCustomClass('http://no.ssl')).toBe('btn btn-sm');
+ expect(component.useCustomClass('http://no.ssl')).toBe('btn');
});
it('should match against multiple functions and return the corresponding classes', () => {
- expect(component.useCustomClass('https://secure.it')).toBe('btn btn-sm secure');
+ expect(component.useCustomClass('https://secure.it')).toBe('btn secure');
});
});
});
ngOnInit() {
const iElement = this.renderer.createElement('i');
- this.renderer.addClass(iElement, 'icon-prepend');
this.renderer.addClass(iElement, 'fa');
this.renderer.addClass(iElement, 'fa-clipboard');
this.renderer.appendChild(this.elementRef.nativeElement, iElement);
ngOnInit() {
this.renderer.setAttribute(this.elementRef.nativeElement, 'tabindex', '-1');
this.iElement = this.renderer.createElement('i');
- this.renderer.addClass(this.iElement, 'icon-prepend');
this.renderer.addClass(this.iElement, 'fa');
this.renderer.appendChild(this.elementRef.nativeElement, this.iElement);
this.update();
exchange = 'fa fa-exchange', // Edit-Peer
copy = 'fa fa-copy', // Copy
clipboard = 'fa fa-clipboard', // Clipboard
- flatten = 'fa-chain-broken', // Flatten, Link broken, Mark Lost
+ flatten = 'fa fa-chain-broken', // Flatten, Link broken, Mark Lost
trash = 'fa fa-trash-o', // Move to trash
lock = 'fa fa-lock', // Protect
unlock = 'fa fa-unlock', // Unprotect
stop = 'fa fa-stop', // Disable
analyse = 'fa fa-stethoscope', // Scrub
deepCheck = 'fa fa-cog', // Deep Scrub, Setting, Configuration
- reweight = 'fa-balance-scale', // Reweight
+ reweight = 'fa fa-balance-scale', // Reweight
left = 'fa fa-arrow-left', // Mark out
right = 'fa fa-arrow-right', // Mark in
down = 'fa fa-arrow-down', // Mark Down
flag = 'fa fa-flag', // OSD configuration
/* Icons for special effect */
- width = 'fa fa-fw', // set one or more icons to the same fixed width
large = 'fa fa-lg', // icon becomes 33% larger
large2x = 'fa fa-2x', // icon becomes 50% larger
large3x = 'fa fa-3x', // icon becomes 3 times larger
-import { ToastOptions } from 'ng2-toastr';
+import { IndividualConfig } from 'ngx-toastr';
import { Icons } from '../enum/icons.enum';
import { NotificationType } from '../enum/notification-type.enum';
public type: NotificationType = NotificationType.info,
public title?: string,
public message?: string, // Use this for additional information only
- public options?: any | ToastOptions,
+ public options?: any | IndividualConfig,
public application: string = 'Ceph'
) {
this.applicationClass = this.classes[this.application];
service.show(NotificationType.info, 'Some info');
expect(toastr.info).toHaveBeenCalledWith(
`<small class="date">${time}</small>` +
- '<i class="pull-right custom-icon ceph-icon" title="Ceph"></i>',
+ '<i class="float-right custom-icon ceph-icon" title="Ceph"></i>',
'Some info',
undefined
);
expect(toastr.error).toHaveBeenCalledWith(
'Some operation failed<br>' +
`<small class="date">${time}</small>` +
- '<i class="pull-right custom-icon ceph-icon" title="Ceph"></i>',
+ '<i class="float-right custom-icon ceph-icon" title="Ceph"></i>',
'Some error',
undefined
);
expect(toastr.success).toHaveBeenCalledWith(
'Some alert resolved<br>' +
`<small class="date">${time}</small>` +
- '<i class="pull-right custom-icon prometheus-icon" title="Prometheus"></i>',
+ '<i class="float-right custom-icon prometheus-icon" title="Prometheus"></i>',
'Alert resolved',
undefined
);
import { Injectable } from '@angular/core';
import * as _ from 'lodash';
-import { ToastOptions, ToastsManager } from 'ng2-toastr';
+import { IndividualConfig, ToastrService } from 'ngx-toastr';
import { BehaviorSubject } from 'rxjs';
import { NotificationType } from '../enum/notification-type.enum';
KEY = 'cdNotifications';
constructor(
- public toastr: ToastsManager,
+ public toastr: ToastrService,
private taskMessageService: TaskMessageService,
private cdDatePipe: CdDatePipe
) {
type: NotificationType,
title: string,
message?: string,
- options?: any | ToastOptions,
+ options?: any | IndividualConfig,
application?: string
): number;
show(config: CdNotificationConfig | (() => CdNotificationConfig)): number;
arg: NotificationType | CdNotificationConfig | (() => CdNotificationConfig),
title?: string,
message?: string,
- options?: any | ToastOptions,
+ options?: any | IndividualConfig,
application?: string
): number {
return window.setTimeout(() => {
renderTimeAndApplicationHtml(notification: CdNotification): string {
return `<small class="date">${this.cdDatePipe.transform(
notification.timestamp
- )}</small><i class="pull-right custom-icon ${notification.applicationClass}" title="${
+ )}</small><i class="float-right custom-icon ${notification.applicationClass}" title="${
notification.application
}"></i>`;
}
+++ /dev/null
-/*The file suppose to contain all variables, mixins and extends*/
-
-@import 'vendor.variables';
-
-$screen-sm-min: 768px !default;
-$screen-md-min: 992px !default;
-$screen-lg-min: 1200px !default;
-
-$screen-xs-max: calc(#{$screen-sm-min} - 1px);
-$screen-sm-max: calc(#{$screen-md-min} - 1px);
-$screen-md-max: calc(#{$screen-lg-min} - 1px);
-
-$color-solid-red: #ff0000 !default;
-$color-pink: #a94442 !default;
-$color-light-red: #f2dede !default;
-
-$color-orange: #ff6600 !default;
-
-$color-bright-yellow: #ffc200 !default;
-$color-light-yellow: #fff3cd !default;
-
-$color-bright-green: #00bb00 !default;
-$color-green: #71843f !default;
-
-$color-blue: #288cea !default;
-$color-light-blue: #d9edf7 !default;
-$color-sky-blue: #afd9ee !default;
-
-$color-black: #000 !default;
-$color-transparent-black: rgba(0, 0, 0, 0.7) !default;
-$color-solid-gray: #555555 !default;
-$color-dark-gray: #474544 !default;
-$color-gray: #505050 !default;
-$color-mild-gray: #777777 !default;
-$color-blue-gray: #90949c !default;
-$color-grad-gray: #ededed !default;
-$color-shadow-gray: rgba(3, 3, 3, 0.175) !default;
-$color-light-gray: #d1d1d1 !default;
-$color-soft-gray: #ddd !default;
-$color-white-gray: #eee !default;
-$color-shade-gray: #efefef !default;
-$color-light-shade-gray: #f3f3f3 !default;
-$color-whitesmoke-gray: #f5f5f5 !default;
-$color-solid-white: #ffffff !default;
-$color-transparent: rgba(0, 0, 0, 0.09) !default;
-$color-brand-teal: #2b99a8 !default;
-$color-brand-gray: #374249 !default;
-
-$color-primary: $color-brand-teal !default;
-$color-secondary: $color-brand-gray !default;
-$color-accent: #ef5c55 !default;
-
-$color-app-bg: $color-solid-white !default;
-$color-bg-darken: $color-dark-gray !default;
-$color-links: $color-primary !default;
-$color-links-focus: $color-dark-gray !default;
-$color-breadcrumb: $color-dark-gray !default;
-$color-button-text: $color-white-gray !default;
-$color-button: $color-primary !default;
-$color-button-hover: darken($color-primary, 3) !default;
-$color-button-border: darken($color-primary, 6) !default;
-$color-button-badge: $color-white-gray !default;
-$color-button-caret: $color-white-gray !default;
-$color-dropdown-menu: $color-dark-gray !default;
-$color-dropdown-active-text: $color-white-gray !default;
-$color-dropdown-active-bg: $color-primary !default;
-$color-caret-text: $color-solid-white !default;
-$color-progress-bar-info-bg: $color-primary !default;
-$color-progress-bar-freespace-bg: $color-light-gray !default;
-$color-oaprogress-text: $color-black !default;
-$color-tags-border: $color-light-gray !default;
-$color-tags-box-shadow: $color-transparent !default;
-$color-error-btn-bg: $color-light-red !default;
-$color-error-btn-border: $color-pink !default;
-$color-noscript-text: $color-mild-gray !default;
-$color-required-text: $color-pink !default;
-
-/*Button*/
-$button-radius: 1.875rem !default;
-
-/*Login*/
-$color-login-row-text: $color-solid-white !default;
-$color-login-row-bg: $color-secondary !default;
-$color-password-toggle-text: $color-solid-white !default;
-$color-password-toggle-bg: $color-solid-gray !default;
-$color-password-toggle-focus: $color-primary !default;
-$color-login-checkbox-bg: $color-primary !default;
-$color-login-checkbox-border: $color-primary !default;
-$color-login-active-row-bg: $color-light-yellow !default;
-$color-login-active-row-text: $color-black !default;
-
-/*Landing Page*/
-
-/*InfoGroup*/
-$color-info-group-underline: $color-whitesmoke-gray !default;
-
-/*InfoCard*/
-$color-info-card-background: $color-whitesmoke-gray !default;
-$color-info-card-border: $color-soft-gray !default;
-
-/*Navigation*/
-$color-navbar-bg: $color-secondary !default;
-$color-navbar-brand: $color-white-gray !default;
-$color-nav-top-bar: $color-primary !default;
-$color-nav-bottom-bar: $color-primary !default;
-$color-nav-toggle-bar: $color-white-gray !default;
-$color-nav-toggle-shadow: $color-solid-white !default;
-$color-nav-collapse-border: $color-white-gray !default;
-$color-nav-open-bg: $color-primary !default;
-$color-nav-links: $color-white-gray !default;
-$color-nav-links-hover: $color-primary !default;
-$color-nav-active-link-bg: $color-primary !default;
-$color-nav-border-top-collapse: $color-white-gray !default;
-
-/*Helper*/
-$color-helper-bg: $color-primary !default;
-
-/*Table*/
-$color-table-seperator-border: $color-transparent !default;
-$color-table-input-border: $color-transparent !default;
-$color-table-dropdown-bg: $color-whitesmoke-gray !default;
-$color-table-header-bg: $color-whitesmoke-gray !default;
-$color-table-header-border: $color-light-gray !default;
-$color-table-active-row: $color-sky-blue !default;
-$color-table-active-row-hover: $color-light-blue !default;
-$color-table-progress-bar-bg: $color-sky-blue !default;
-$color-table-progress-bar-active: $color-primary !default;
-$color-table-gradient-1: $color-whitesmoke-gray !default;
-$color-table-gradient-2: $color-grad-gray !default;
-$color-table-sort: $color-primary !default;
-$color-table-empty-row: $color-light-yellow !default;
-$color-table-hover-row: $color-white-gray !default;
-$color-table-even-row-bg: $color-solid-white !default;
-$color-table-odd-row-bg: $color-whitesmoke-gray !default;
-$color-table-datatable-header: $color-whitesmoke-gray !default;
-
-/*Chart tooltip*/
-$color-chart-tooltip-bg: $color-transparent-black !default;
-$color-chat-tooltip-text: $color-solid-white !default;
-$color-chart-tooltip-border: $color-black !default;
-
-/*Popover*/
-$color-popover-seperator-text: $color-blue-gray !default;
-$color-popover-seperator-bg: $color-white-gray !default;
-$color-popover-message-text: $color-dark-gray !default;
-$color-popover-table-text: $color-dark-gray !default;
-$color-popover-date: $color-solid-gray !default;
-
-/*RGW user form*/
-$color-rgw-icon: $color-blue-gray !default;
-
-@mixin table-cell {
- padding: 5px;
- border: none;
- border-left: 1px solid $color-light-gray;
- border-bottom: 1px solid $color-light-gray;
-}
-
-@mixin hf {
- border-bottom: 1px solid $color-light-gray;
- background-color: $color-whitesmoke-gray;
-}
-
-@function strip-unit($value) {
- @return $value / ($value * 0 + 1);
-}
-
-@mixin fluid-font-size($min-vw, $max-vw, $min-font-size, $max-font-size) {
- $u1: unit($min-vw);
- $u2: unit($max-vw);
- $u3: unit($min-font-size);
- $u4: unit($max-font-size);
-
- @if $u1 == $u2 and $u1 == $u3 and $u1 == $u4 {
- & {
- font-size: $min-font-size;
- @media screen and (min-width: $min-vw) {
- font-size: calc(
- #{$min-font-size} + #{strip-unit($max-font-size - $min-font-size)} *
- ((100vw - #{$min-vw}) / #{strip-unit($max-vw - $min-vw)})
- );
- }
- @media screen and (min-width: $max-vw) {
- font-size: $max-font-size;
- }
- }
- }
-}
document.write('<base href="' + document.location+ '" />');
</script>
- <meta name="viewport" content="width=device-width, initial-scale=1">
+ <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
/* You can add global styles to this file, and also import other style files */
-
@import 'defaults';
-$fa-font-path: '../node_modules/fork-awesome/fonts';
-@import '../node_modules/fork-awesome/scss/fork-awesome';
-$font_family_1: 'ForkAwesome';
+
+// Fork-Awesome
+$fa-font-path: '~fork-awesome/fonts';
+$font-family-icon: 'ForkAwesome';
+
+// Bootstrap
+$theme-colors: (
+ 'primary': $color-primary,
+ 'secondary': $color-accent,
+ 'dark': $color-mild-gray
+);
+
+$font-family-sans-serif: 'Helvetica Neue', Helvetica, Arial, 'Noto Sans', sans-serif,
+ 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+
+$badge-font-size: 1rem;
+
+@import '~bootstrap/scss/bootstrap';
+@import '~fork-awesome/scss/fork-awesome';
@import 'app/ceph/dashboard/info-card/info-card-popover.scss';
/* Basics */
height: 100%;
font-size: 12px;
}
-a {
- color: $color-links;
- cursor: pointer;
-}
-a:hover,
-a:focus {
- color: $color-links-focus;
-}
h1 {
letter-spacing: -1px;
font-size: 2em;
font-weight: normal;
font-style: normal;
}
-/* For awesome-bootstrap-checkbox */
-.checkbox input[type='checkbox']:checked + label:after {
- font-family: $font_family_1;
-}
-/*******/
+
.full-height {
height: 100%;
}
}
/* Buttons */
+.btn-light {
+ background-color: $color-solid-white !important;
+ border-color: $color-input-border !important;
+
+ &:hover {
+ background-color: $color-soft-gray !important;
+ border-color: $color-input-border-hover !important;
+ }
+}
+
+.btn-secondary,
+.btn-light {
+ border-radius: $button-radius;
+}
+
+form .input-group .btn-light {
+ border-radius: $border-radius;
+}
+
+// We have some inputs that don't have a corresponding formControlName,
+// to be able to get the same styling and no JS errors we need use a different
+// class name
+.cd-form-control {
+ @extend .form-control;
+}
+
.btn {
&,
&:active,
}
}
}
-.btn-primary {
- color: $color-button-text;
- background-color: $color-accent;
- border-color: $color-accent;
- border-radius: $button-radius;
-}
-.btn-primary:hover,
-.btn-primary:focus,
-.btn-primary:active,
-.btn-primary.active,
-.open .dropdown-toggle.btn-primary {
- color: $color-button-text;
- background-color: lighten($color-accent, 10);
- border-color: lighten($color-accent, 10);
-}
-.btn-primary:active,
-.btn-primary.active,
-.open .dropdown-toggle.btn-primary {
- background-image: none;
-
- &:hover,
- &:focus {
- background-color: lighten($color-accent, 10);
- border-color: lighten($color-accent, 10);
- }
-}
-.btn-primary.disabled,
-.btn-primary[disabled],
-fieldset[disabled] .btn-primary,
-.btn-primary.disabled:hover,
-.btn-primary[disabled]:hover,
-fieldset[disabled] .btn-primary:hover,
-.btn-primary.disabled:focus,
-.btn-primary[disabled]:focus,
-fieldset[disabled] .btn-primary:focus,
-.btn-primary.disabled:active,
-.btn-primary[disabled]:active,
-fieldset[disabled] .btn-primary:active,
-.btn-primary.disabled.active,
-.btn-primary[disabled].active,
-fieldset[disabled] .btn-primary.active {
- background-color: $color-accent;
- border-color: $color-accent;
-}
.btn-primary .badge {
color: $color-primary;
background-color: $color-button-badge;
}
-.btn-default {
- border-radius: $button-radius;
-}
-.form-group .btn-default {
- border-radius: 4px;
-}
.btn-group > .btn > i.fa,
-button.btn.btn-label > i.fa {
+.cd-datatable-actions button.btn i.fa {
/** Add space between icon and text */
- padding-right: 5px;
+ margin-right: 5px;
}
/* Dropdown */
}
.dropdown-menu > li > a > i.fa {
/** Add space between icon and text */
- padding-right: 5px;
+ margin-right: 5px;
}
.dropdown-menu > .active > a {
color: $color-dropdown-active-text;
background-color: darken($color-dropdown-active-bg, 10);
}
}
-.dataTables_wrapper .dropdown-menu > li.divider {
+.dataTables_wrapper .dropdown-menu > li.dropdown-divider {
cursor: auto;
}
/* Grid */
.container,
.container-fluid {
- padding-left: 30px;
- padding-right: 30px;
+ padding-left: 30px !important;
+ padding-right: 30px !important;
}
.row {
margin-left: -30px;
.col-sm-7,
.col-sm-8,
.col-sm-9,
-.col-xs-1,
-.col-xs-10,
-.col-xs-11,
-.col-xs-12,
-.col-xs-2,
-.col-xs-3,
-.col-xs-4,
-.col-xs-5,
-.col-xs-6,
-.col-xs-7,
-.col-xs-8,
-.col-xs-9 {
+.col-1,
+.col-10,
+.col-11,
+.col-12,
+.col-2,
+.col-3,
+.col-4,
+.col-5,
+.col-6,
+.col-7,
+.col-8,
+.col-9 {
padding-left: 30px;
padding-right: 30px;
}
-/* Progressbar */
-.progress-bar {
- background-image: none !important;
-}
-.progress-bar-info {
- background-color: $color-progress-bar-info-bg;
-}
-.progress-bar-freespace {
- background-color: $color-progress-bar-freespace-bg;
-}
-.oaprogress {
- position: relative;
- margin-bottom: 0;
-}
-.oaprogress div.progress-bar {
- position: static;
-}
-.oaprogress span {
- position: absolute;
- display: block;
- width: 100%;
- color: $color-oaprogress-text;
- font-weight: normal;
-}
tags-input .tags {
border-radius: 4px;
border: 1px solid $color-tags-border;
box-shadow: inset 0 1px 1px $color-tags-box-shadow;
}
-uib-accordion .panel-title,
-.panel .accordion-title {
+uib-accordion .card-title,
+.card .accordion-title {
font-size: 14px !important;
}
-.panel-body h2:first-child {
- margin-top: 0;
+.card-header {
+ font-size: 1.3em;
}
-.pull-left {
- float: left;
+.card-body h2:first-child {
+ margin-top: 0;
}
.disabled {
pointer-events: none;
}
-.clickable {
+.clickable,
+a {
cursor: pointer;
}
-.has-error .has-error-btn,
-.has-error .has-error-btn:disabled:hover {
+:invalid .has-error-btn,
+:invalid .has-error-btn:disabled:hover {
background-color: $color-error-btn-bg;
border-color: $color-error-btn-border;
}
color: $color-required-text;
}
/* Forms */
-.form-group > .control-label > span.required {
+.form-group > .col-form-label > span.required {
@extend .fa;
@extend .fa-asterisk;
@extend .required;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px 2px rgba($color-primary, 0.5);
}
}
-/* Panel */
-.panel-footer button.btn:not(:first-child) {
+
+.custom-checkbox {
+ padding-top: 7px;
+}
+
+/* Card */
+.card-footer button.btn:not(:first-child) {
margin-left: 5px;
}
/* Modal dialog */
.modal-footer button.btn:not(:first-child) {
margin-left: 5px;
}
-.margin-right-sm {
- margin-right: 10px;
-}
.nav-tabs {
margin-bottom: 15px;
}
background: $color-transparent-black !important;
}
-h3.page-header {
- margin-left: 1em;
- margin-top: 1em;
- border-color: #f0f0f0;
-}
-
.tooltip-wide .tooltip-inner {
width: 400px;
}
padding-left: 1em;
margin: 0;
}
+
+.cd-header,
+legend {
+ @extend .pb-1;
+ @extend .mt-4;
+ @extend .mb-4;
+ @extend .border-bottom;
+}
+
+@include media-breakpoint-up(sm) {
+ .col-form-label {
+ text-align: right;
+ }
+}
+
+.form-group > label {
+ font-weight: 700;
+}
+
+// Firefox is adding a white background-coor in these components
+cd-submit-button {
+ background-color: transparent !important;
+}
+
+// All '.fa' icons will have fixed width
+.fa {
+ @extend .fa-fw;
+}
+
+pre {
+ @extend .card;
+ @extend .bg-light;
+ @extend .p-2;
+ // @extend my-2;
+}
-@import '../defaults';
+@import 'defaults';
.chart-container {
position: absolute;
--- /dev/null
+/*The file suppose to contain all variables, mixins and extends*/
+
+@import 'vendor.variables';
+
+$screen-sm-min: 576px !default;
+$screen-md-min: 768px !default;
+$screen-lg-min: 992px !default;
+$screen-xl-min: 1200px !default;
+
+$screen-xs-max: calc(#{$screen-sm-min} - 1px);
+$screen-sm-max: calc(#{$screen-md-min} - 1px);
+$screen-md-max: calc(#{$screen-lg-min} - 1px);
+$screen-lg-max: calc(#{$screen-xl-min} - 1px);
+
+$color-solid-red: #ff0000 !default;
+$color-pink: #a94442 !default;
+$color-light-red: #f2dede !default;
+
+// $color-orange: #ff6600 !default;
+
+$color-bright-yellow: #ffc200 !default;
+$color-light-yellow: #fff3cd !default;
+
+$color-bright-green: #00bb00 !default;
+// $color-green: #71843f !default;
+
+$color-blue: #288cea !default;
+$color-light-blue: #d1ecf1 !default;
+$color-sky-blue: #afd9ee !default;
+
+$color-black: #000 !default;
+$color-transparent-black: rgba(0, 0, 0, 0.7) !default;
+$color-solid-gray: #555555 !default;
+$color-dark-gray: #474544 !default;
+// $color-gray: #505050 !default;
+$color-mild-gray: #777777 !default;
+$color-blue-gray: #90949c !default;
+$color-grad-gray: #ededed !default;
+$color-shadow-gray: rgba(3, 3, 3, 0.175) !default;
+$color-light-gray: #d1d1d1 !default;
+$color-soft-gray: #ddd !default;
+$color-white-gray: #eee !default;
+$color-shade-gray: #efefef !default;
+$color-light-shade-gray: #f3f3f3 !default;
+$color-whitesmoke-gray: #f5f5f5 !default;
+$color-solid-white: #ffffff !default;
+$color-transparent: rgba(0, 0, 0, 0.09) !default;
+$color-input-border: #ced4da;
+$color-input-border-hover: #adadad;
+$color-brand-teal: #2b99a8 !default;
+$color-brand-gray: #374249 !default;
+
+$color-primary: $color-brand-teal !default;
+$color-secondary: $color-brand-gray !default;
+$color-accent: #ef5c55 !default;
+
+$color-app-bg: $color-solid-white !default;
+// $color-bg-darken: $color-dark-gray !default;
+// $color-links: $color-primary !default;
+// $color-links-focus: $color-dark-gray !default;
+$color-breadcrumb: $color-dark-gray !default;
+// $color-button-text: $color-white-gray !default;
+$color-button: $color-primary !default;
+// $color-button-hover: darken($color-primary, 3) !default;
+// $color-button-border: darken($color-primary, 6) !default;
+$color-button-badge: $color-white-gray !default;
+$color-dropdown-menu: $color-dark-gray !default;
+$color-dropdown-active-text: $color-white-gray !default;
+$color-dropdown-active-bg: $color-primary !default;
+$color-progress-bar-info-bg: $color-primary !default;
+$color-progress-bar-freespace-bg: $color-light-gray !default;
+$color-progress-text: $color-black !default;
+$color-tags-border: $color-light-gray !default;
+$color-tags-box-shadow: $color-transparent !default;
+$color-error-btn-bg: $color-light-red !default;
+$color-error-btn-border: $color-pink !default;
+$color-noscript-text: $color-mild-gray !default;
+$color-required-text: $color-pink !default;
+
+/*Button*/
+$button-radius: 1.875rem !default;
+
+/*Login*/
+$color-login-row-text: $color-solid-white !default;
+$color-login-row-bg: $color-secondary !default;
+$color-password-toggle-text: $color-solid-white !default;
+$color-password-toggle-bg: $color-solid-gray !default;
+$color-password-toggle-focus: $color-primary !default;
+// $color-login-active-row-bg: $color-light-yellow !default;
+// $color-login-active-row-text: $color-black !default;
+
+/*Landing Page*/
+
+/*InfoGroup*/
+// $color-info-group-underline: $color-whitesmoke-gray !default;
+
+/*InfoCard*/
+// $color-info-card-background: $color-whitesmoke-gray !default;
+$color-info-card-border: $color-soft-gray !default;
+
+/*Navigation*/
+$color-navbar-bg: $color-secondary !default;
+$color-navbar-brand: $color-white-gray !default;
+$color-nav-top-bar: $color-primary !default;
+$color-nav-bottom-bar: $color-primary !default;
+$color-nav-toggle-bar: $color-white-gray !default;
+$color-nav-toggle-shadow: $color-solid-white !default;
+$color-nav-collapse-border: $color-white-gray !default;
+$color-nav-open-bg: $color-primary !default;
+$color-nav-links: $color-white-gray !default;
+$color-nav-links-hover: $color-primary !default;
+$color-nav-active-link-bg: $color-primary !default;
+$color-nav-border-top-collapse: $color-white-gray !default;
+
+/*Helper*/
+$color-helper-bg: $color-primary !default;
+
+/*Table*/
+$color-table-seperator-border: $color-transparent !default;
+$color-table-input-border: $color-transparent !default;
+$color-table-dropdown-bg: $color-whitesmoke-gray !default;
+$color-table-header-bg: $color-whitesmoke-gray !default;
+$color-table-header-border: $color-light-gray !default;
+$color-table-active-row: $color-sky-blue !default;
+$color-table-active-row-hover: $color-light-blue !default;
+// $color-table-progress-bar-bg: $color-sky-blue !default;
+$color-table-progress-bar-active: $color-primary !default;
+$color-table-gradient-1: $color-whitesmoke-gray !default;
+$color-table-gradient-2: $color-grad-gray !default;
+$color-table-sort: $color-primary !default;
+$color-table-empty-row: $color-light-yellow !default;
+$color-table-hover-row: $color-white-gray !default;
+$color-table-even-row-bg: $color-solid-white !default;
+$color-table-odd-row-bg: $color-whitesmoke-gray !default;
+$color-table-datatable-header: $color-whitesmoke-gray !default;
+
+/*Chart tooltip*/
+$color-chart-tooltip-bg: $color-transparent-black !default;
+$color-chat-tooltip-text: $color-solid-white !default;
+$color-chart-tooltip-border: $color-black !default;
+
+/*Popover*/
+$color-popover-seperator-text: $color-blue-gray !default;
+$color-popover-seperator-bg: $color-white-gray !default;
+$color-popover-message-text: $color-dark-gray !default;
+$color-popover-table-text: $color-dark-gray !default;
+$color-popover-date: $color-solid-gray !default;
+
+/*RGW user form*/
+$color-rgw-icon: $color-blue-gray !default;
+
+@mixin table-cell {
+ padding: 5px;
+ border: none;
+ border-left: 1px solid $color-light-gray;
+ border-bottom: 1px solid $color-light-gray;
+}
+
+@mixin hf {
+ border-bottom: 1px solid $color-light-gray;
+ background-color: $color-whitesmoke-gray;
+}
+
+@function strip-unit($value) {
+ @return $value / ($value * 0 + 1);
+}
+
+@mixin fluid-font-size($min-vw, $max-vw, $min-font-size, $max-font-size) {
+ $u1: unit($min-vw);
+ $u2: unit($max-vw);
+ $u3: unit($min-font-size);
+ $u4: unit($max-font-size);
+
+ @if $u1 == $u2 and $u1 == $u3 and $u1 == $u4 {
+ & {
+ font-size: $min-font-size;
+ @media screen and (min-width: $min-vw) {
+ font-size: calc(
+ #{$min-font-size} + #{strip-unit($max-font-size - $min-font-size)} *
+ ((100vw - #{$min-vw}) / #{strip-unit($max-vw - $min-vw)})
+ );
+ }
+ @media screen and (min-width: $max-vw) {
+ font-size: $max-font-size;
+ }
+ }
+ }
+}
-@import '../defaults';
+@import 'defaults';
::ng-deep .popover-content {
padding: 0.5em;
--- /dev/null
+/* Vendor specific scss */
+
+@import 'defaults';
--- /dev/null
+/* Vendor specific variables */\r
+++ /dev/null
-/* Vendor specific scss */
-
-@import 'defaults';
+++ /dev/null
-/* Vendor specific variables */\r