├── js ├── directives │ ├── PackagesDirective.js │ ├── FooterDirective.js │ ├── LoaderDirective.js │ ├── LoaderDirective.1.js │ ├── PackageExplorerDirective.js │ ├── ActivityBarDirective.js │ ├── PackageExplorerListItemDirective.js │ ├── PackageListItemDirective.js │ ├── SettingsDirective.js │ ├── PackageListDirective.js │ ├── PackageInitDirective.js │ ├── PackageExplorerListDirective.js │ ├── PackageDirective.js │ └── PackageDetailDirective.js ├── interfaces │ ├── IPackage.js │ ├── IPackagest.js │ ├── IPackageCommand.js │ ├── IPackageControl.js │ ├── IPackageDetail.js │ ├── IPackageExplorer.js │ └── IPackageExplorerItem.js ├── helpers │ ├── ConstantHelpers.js │ ├── StatusHelpers.js │ ├── WindowHelpers.js │ ├── MessageDialogHelpers.js │ ├── PackageExplorerHelpers.js │ └── PackageInitFileHelpers.js ├── controller │ └── MainController.js ├── app.js └── services │ ├── NpmService.js │ └── BowerService.js ├── images ├── app.ico ├── app.png ├── themes │ ├── dark-theme.jpg │ ├── light-theme.jpg │ ├── dark-theme-big.jpg │ └── light-theme-big.jpg ├── documentation │ ├── readme-main.gif │ ├── process │ │ ├── install.gif │ │ ├── uninstall.gif │ │ ├── dependencies.gif │ │ ├── init-packages.gif │ │ ├── update-specify-version.gif │ │ ├── check-if-exist-any-update.gif │ │ ├── downgrade-specify-version.gif │ │ ├── install-specify-version.gif │ │ └── update-to-latest-version.gif │ ├── open-packages │ │ ├── npm.gif │ │ └── bower.gif │ ├── global-packages │ │ └── view.png │ ├── settings │ │ ├── change-theme.gif │ │ └── restore-to-defaults.gif │ └── search-mechanism │ │ ├── search-clear.gif │ │ ├── classic-search.gif │ │ ├── search-inside-update.gif │ │ ├── search-inside-installed.gif │ │ ├── search-inside-dependencies.gif │ │ ├── search-inside-devdependencies.gif │ │ ├── search-inside-update-manually.gif │ │ └── search-inside-installed-manually.gif ├── electron-webapp-previews │ ├── npm-init.png │ ├── bower-init.png │ ├── dark-theme.png │ └── light-theme.png └── activity-bar-icons │ ├── npm.svg │ └── bower.svg ├── templates ├── loader.html ├── package-explorer.html ├── package-list.html ├── footer.html ├── activity-bar.html ├── package-explorer-list.html ├── packages.html ├── package-list-item.html ├── settings.html └── package-detail.html ├── src ├── scss │ ├── _key-frames.scss │ ├── _mixins.scss │ ├── _footer.scss │ ├── _navtabs.scss │ ├── _buttons.scss │ ├── _modal.scss │ ├── _message-dialog.scss │ ├── _activity-bar.scss │ ├── _helpers.scss │ ├── _settings.scss │ ├── _package-explorer.scss │ ├── style.scss │ └── _packages.scss └── js │ ├── interfaces │ ├── IPackagest.ts │ ├── IPackageCommand.ts │ ├── IPackageExplorer.ts │ ├── IPackageControl.ts │ ├── IPackageDetail.ts │ └── IPackage.ts │ ├── directives │ ├── FooterDirective.ts │ ├── LoaderDirective.ts │ ├── PackageExplorerDirective.ts │ ├── ActivityBarDirective.ts │ ├── PackageListItemDirective.ts │ ├── SettingsDirective.ts │ ├── PackageListDirective.ts │ ├── PackageInitDirective.ts │ ├── PackageExplorerListDirective.ts │ ├── PackageDirective.ts │ └── PackageDetailDirective.ts │ ├── helpers │ ├── ConstantHelpers.ts │ ├── StatusHelpers.ts │ ├── WindowHelpers.ts │ ├── MessageDialogHelpers.ts │ ├── PackageExplorerHelpers.ts │ └── PackageInitFileHelpers.ts │ ├── controller │ └── MainController.ts │ ├── app.ts │ └── services │ ├── NpmService.ts │ └── BowerService.ts ├── gulpfile.js ├── tsconfig.json ├── index.js ├── LICENSE ├── .gitignore ├── index.html ├── package.json └── README.md /js/directives/PackagesDirective.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/app.ico -------------------------------------------------------------------------------- /images/app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/app.png -------------------------------------------------------------------------------- /js/interfaces/IPackage.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /js/interfaces/IPackagest.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /js/interfaces/IPackageCommand.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /js/interfaces/IPackageControl.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /js/interfaces/IPackageDetail.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /js/interfaces/IPackageExplorer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | -------------------------------------------------------------------------------- /templates/loader.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Please wait...

4 |
-------------------------------------------------------------------------------- /images/themes/dark-theme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/themes/dark-theme.jpg -------------------------------------------------------------------------------- /images/themes/light-theme.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/themes/light-theme.jpg -------------------------------------------------------------------------------- /images/themes/dark-theme-big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/themes/dark-theme-big.jpg -------------------------------------------------------------------------------- /images/themes/light-theme-big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/themes/light-theme-big.jpg -------------------------------------------------------------------------------- /images/documentation/readme-main.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/readme-main.gif -------------------------------------------------------------------------------- /images/documentation/process/install.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/install.gif -------------------------------------------------------------------------------- /images/documentation/open-packages/npm.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/open-packages/npm.gif -------------------------------------------------------------------------------- /images/documentation/process/uninstall.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/uninstall.gif -------------------------------------------------------------------------------- /images/documentation/global-packages/view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/global-packages/view.png -------------------------------------------------------------------------------- /images/documentation/open-packages/bower.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/open-packages/bower.gif -------------------------------------------------------------------------------- /images/documentation/process/dependencies.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/dependencies.gif -------------------------------------------------------------------------------- /images/electron-webapp-previews/npm-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/electron-webapp-previews/npm-init.png -------------------------------------------------------------------------------- /src/scss/_key-frames.scss: -------------------------------------------------------------------------------- 1 | @keyframes spin { 2 | 0% { 3 | transform: rotate(0deg); 4 | } 5 | 100% { 6 | transform: rotate(360deg); 7 | } 8 | } -------------------------------------------------------------------------------- /images/documentation/process/init-packages.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/init-packages.gif -------------------------------------------------------------------------------- /images/documentation/settings/change-theme.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/settings/change-theme.gif -------------------------------------------------------------------------------- /images/electron-webapp-previews/bower-init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/electron-webapp-previews/bower-init.png -------------------------------------------------------------------------------- /images/electron-webapp-previews/dark-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/electron-webapp-previews/dark-theme.png -------------------------------------------------------------------------------- /images/electron-webapp-previews/light-theme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/electron-webapp-previews/light-theme.png -------------------------------------------------------------------------------- /images/documentation/settings/restore-to-defaults.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/settings/restore-to-defaults.gif -------------------------------------------------------------------------------- /images/documentation/process/update-specify-version.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/update-specify-version.gif -------------------------------------------------------------------------------- /images/documentation/search-mechanism/search-clear.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/search-mechanism/search-clear.gif -------------------------------------------------------------------------------- /images/documentation/process/check-if-exist-any-update.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/check-if-exist-any-update.gif -------------------------------------------------------------------------------- /images/documentation/process/downgrade-specify-version.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/downgrade-specify-version.gif -------------------------------------------------------------------------------- /images/documentation/process/install-specify-version.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/install-specify-version.gif -------------------------------------------------------------------------------- /images/documentation/process/update-to-latest-version.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/process/update-to-latest-version.gif -------------------------------------------------------------------------------- /images/documentation/search-mechanism/classic-search.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/search-mechanism/classic-search.gif -------------------------------------------------------------------------------- /src/js/interfaces/IPackagest.ts: -------------------------------------------------------------------------------- 1 | export interface IPackagest { 2 | title: string; 3 | packageManager: string; 4 | file: string; 5 | isExistDevDependencies: boolean; 6 | } -------------------------------------------------------------------------------- /images/documentation/search-mechanism/search-inside-update.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/search-mechanism/search-inside-update.gif -------------------------------------------------------------------------------- /images/documentation/search-mechanism/search-inside-installed.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/search-mechanism/search-inside-installed.gif -------------------------------------------------------------------------------- /images/documentation/search-mechanism/search-inside-dependencies.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/search-mechanism/search-inside-dependencies.gif -------------------------------------------------------------------------------- /images/documentation/search-mechanism/search-inside-devdependencies.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/search-mechanism/search-inside-devdependencies.gif -------------------------------------------------------------------------------- /images/documentation/search-mechanism/search-inside-update-manually.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/search-mechanism/search-inside-update-manually.gif -------------------------------------------------------------------------------- /images/documentation/search-mechanism/search-inside-installed-manually.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/HEAD/images/documentation/search-mechanism/search-inside-installed-manually.gif -------------------------------------------------------------------------------- /src/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin three-dots-overflow() { 2 | white-space: nowrap; 3 | -ms-text-overflow: ellipsis; 4 | -o-text-overflow: ellipsis; 5 | text-overflow: ellipsis; 6 | overflow: hidden; 7 | } -------------------------------------------------------------------------------- /src/js/interfaces/IPackageCommand.ts: -------------------------------------------------------------------------------- 1 | export interface IPackageCommand { 2 | packages: string[]; 3 | dependsOn?: string[]; 4 | isDevDependency?: boolean; 5 | packagePath?: string; 6 | isGlobal?: boolean; 7 | } -------------------------------------------------------------------------------- /src/js/interfaces/IPackageExplorer.ts: -------------------------------------------------------------------------------- 1 | export interface IPackageExplorer { 2 | caption: string; 3 | path: string; 4 | packageManager: string; 5 | canDelete: boolean; 6 | isExistDevDependencies: boolean; 7 | } -------------------------------------------------------------------------------- /src/js/interfaces/IPackageControl.ts: -------------------------------------------------------------------------------- 1 | export interface IPackageControl { 2 | install: boolean; 3 | uninstall: boolean; 4 | loader?: boolean; 5 | update: boolean; 6 | reload: boolean; 7 | downgrade?: boolean; 8 | } -------------------------------------------------------------------------------- /templates/package-explorer.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
-------------------------------------------------------------------------------- /templates/package-list.html: -------------------------------------------------------------------------------- 1 |
-- No packages --
2 | -------------------------------------------------------------------------------- /src/scss/_footer.scss: -------------------------------------------------------------------------------- 1 | footer { 2 | height: 24px; 3 | font-size: 12px; 4 | display: table; 5 | width: 100%; 6 | 7 | .footer-container { 8 | padding-left: 5px; 9 | padding-right: 5px; 10 | display: table-cell; 11 | vertical-align: middle; 12 | } 13 | } -------------------------------------------------------------------------------- /js/interfaces/IPackageExplorerItem.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var IPackageExplorerItem = (function () { 4 | function IPackageExplorerItem() { 5 | } 6 | return IPackageExplorerItem; 7 | }()); 8 | exports.IPackageExplorerItem = IPackageExplorerItem; 9 | -------------------------------------------------------------------------------- /src/scss/_navtabs.scss: -------------------------------------------------------------------------------- 1 | .nav-tabs { 2 | 3 | >li { 4 | > a { 5 | border-radius: 0; 6 | border: none !important; 7 | font-size: 13px; 8 | font-weight: 600; 9 | } 10 | } 11 | } 12 | 13 | .tab-content { 14 | > .tab-pane { 15 | padding: 10px 12px; 16 | } 17 | } -------------------------------------------------------------------------------- /src/js/interfaces/IPackageDetail.ts: -------------------------------------------------------------------------------- 1 | export interface IPackageDetail { 2 | name: string; 3 | author?: string; 4 | license?: string; 5 | description?: string; 6 | versions?: string[]; 7 | version?: string; 8 | readMe?: string; 9 | contributors?: any; 10 | dependencies?: any; 11 | devDependencies?: any; 12 | } -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var sass = require('gulp-sass'); 3 | 4 | gulp.task('sass', function () { 5 | return gulp.src('./src/scss/**/*.scss') 6 | .pipe(sass().on('error', sass.logError)) 7 | .pipe(gulp.dest('./css/')); 8 | }); 9 | 10 | gulp.task('default', function () { 11 | gulp.watch('./src/scss/**/*.scss', ['sass']); 12 | }); -------------------------------------------------------------------------------- /src/scss/_buttons.scss: -------------------------------------------------------------------------------- 1 | .btn { 2 | border: none; 3 | border-radius: 0; 4 | } 5 | 6 | .btn-group { 7 | > .btn { 8 | + .dropdown-toggle { 9 | padding-left: 3px; 10 | padding-right: 3px; 11 | } 12 | } 13 | 14 | &.open { 15 | .dropdown-toggle { 16 | box-shadow: none; 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/js/directives/FooterDirective.ts: -------------------------------------------------------------------------------- 1 | export class FooterDirective { 2 | restrict: string; 3 | templateUrl: string; 4 | transclude: boolean; 5 | 6 | constructor() { 7 | this.restrict = 'E' 8 | this.templateUrl = './templates/footer.html' 9 | this.transclude = true 10 | } 11 | 12 | link(scope: any, element: any, attrs: any) { } 13 | } -------------------------------------------------------------------------------- /src/js/directives/LoaderDirective.ts: -------------------------------------------------------------------------------- 1 | export class LoaderDirective { 2 | restrict: string; 3 | templateUrl: string; 4 | transclude: boolean; 5 | 6 | constructor() { 7 | this.restrict = 'E' 8 | this.templateUrl = './templates/loader.html' 9 | this.transclude = true 10 | } 11 | 12 | link(scope: any, element: any, attrs: any) { } 13 | } -------------------------------------------------------------------------------- /src/js/interfaces/IPackage.ts: -------------------------------------------------------------------------------- 1 | import { IPackageControl } from './IPackageControl'; 2 | 3 | export interface IPackage { 4 | name?: string; 5 | version?: string; 6 | alreadyInstalled?: boolean; 7 | listItemControl?: IPackageControl; 8 | detailControl?: IPackageControl; 9 | latestVersion?: string; 10 | selectedVersion?: string; 11 | isDevDependencies?: boolean; 12 | } -------------------------------------------------------------------------------- /templates/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /js/directives/FooterDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var FooterDirective = (function () { 4 | function FooterDirective() { 5 | this.restrict = 'E'; 6 | this.templateUrl = './templates/footer.html'; 7 | this.transclude = true; 8 | } 9 | FooterDirective.prototype.link = function (scope, element, attrs) { }; 10 | return FooterDirective; 11 | }()); 12 | exports.FooterDirective = FooterDirective; 13 | -------------------------------------------------------------------------------- /js/directives/LoaderDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var LoaderDirective = (function () { 4 | function LoaderDirective() { 5 | this.restrict = 'E'; 6 | this.templateUrl = './templates/loader.html'; 7 | this.transclude = true; 8 | } 9 | LoaderDirective.prototype.link = function (scope, element, attrs) { }; 10 | return LoaderDirective; 11 | }()); 12 | exports.LoaderDirective = LoaderDirective; 13 | -------------------------------------------------------------------------------- /js/directives/LoaderDirective.1.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var LoaderDirective = (function () { 4 | function LoaderDirective() { 5 | this.restrict = 'E'; 6 | this.templateUrl = './templates/loader.html'; 7 | this.transclude = true; 8 | } 9 | LoaderDirective.prototype.link = function (scope, element, attrs) { }; 10 | return LoaderDirective; 11 | }()); 12 | exports.LoaderDirective = LoaderDirective; 13 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": true, 3 | "compilerOptions": { 4 | "module": "commonjs", 5 | "target": "es5", 6 | "sourceMap": false, 7 | "noImplicitAny": true, 8 | "removeComments": true, 9 | "preserveConstEnums": true, 10 | "outDir": "js", 11 | "watch": true 12 | }, 13 | "include": [ 14 | "src/js/**/*.ts" 15 | ], 16 | "exclude": [ 17 | "node_modules", 18 | "**/*.spec.ts" 19 | ] 20 | } -------------------------------------------------------------------------------- /src/scss/_modal.scss: -------------------------------------------------------------------------------- 1 | .modal-content { 2 | border-radius: 0; 3 | 4 | .modal-header { 5 | padding: 12px 14px; 6 | 7 | .close { 8 | text-shadow: none; 9 | font-size: 22px; 10 | opacity: 0.5; 11 | 12 | &:hover, 13 | &:active { 14 | opacity: 0.75; 15 | } 16 | } 17 | 18 | .modal-title { 19 | font-size: 14px; 20 | font-weight: 600; 21 | } 22 | } 23 | 24 | .modal-footer { 25 | border: none; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /templates/activity-bar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/scss/_message-dialog.scss: -------------------------------------------------------------------------------- 1 | .noty_bar { 2 | border: none !important; 3 | border-radius: 0 !important; 4 | font-size: 13px; 5 | text-align: center; 6 | 7 | .noty_body { 8 | font-size: 13px !important; 9 | padding: 13px !important; 10 | } 11 | 12 | &.noty_has_progressbar { 13 | .noty_progressbar { 14 | background-color: #000 !important; 15 | } 16 | } 17 | 18 | &.noty_type__error { 19 | background-color: #660000; 20 | } 21 | 22 | &.noty_type__success { 23 | background-color: #327E36; 24 | } 25 | } 26 | 27 | #noty_layout__topCenter { 28 | top: 10px !important; 29 | } -------------------------------------------------------------------------------- /src/js/directives/PackageExplorerDirective.ts: -------------------------------------------------------------------------------- 1 | import { MessageDialogHelpers } from "../helpers/MessageDialogHelpers"; 2 | import { PackageExplorerHelpers } from '../helpers/PackageExplorerHelpers'; 3 | 4 | export class PackageExplorerDirective { 5 | restrict: string; 6 | templateUrl: string; 7 | transclude: boolean; 8 | 9 | constructor() { 10 | this.restrict = 'E' 11 | this.templateUrl = './templates/package-explorer.html' 12 | this.transclude = true 13 | } 14 | 15 | link(scope: any, element: any, attrs: any) { 16 | scope.$root.packagePathList = {}; 17 | 18 | scope.$root.activityBarIcons.forEach((value: any, i: number) => { 19 | scope.$root.packagePathList[value.packageManager] = new PackageExplorerHelpers().getListItem(value.packageManager); 20 | }); 21 | } 22 | } -------------------------------------------------------------------------------- /js/directives/PackageExplorerDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var PackageExplorerHelpers_1 = require("../helpers/PackageExplorerHelpers"); 4 | var PackageExplorerDirective = (function () { 5 | function PackageExplorerDirective() { 6 | this.restrict = 'E'; 7 | this.templateUrl = './templates/package-explorer.html'; 8 | this.transclude = true; 9 | } 10 | PackageExplorerDirective.prototype.link = function (scope, element, attrs) { 11 | scope.$root.packagePathList = {}; 12 | scope.$root.activityBarIcons.forEach(function (value, i) { 13 | scope.$root.packagePathList[value.packageManager] = new PackageExplorerHelpers_1.PackageExplorerHelpers().getListItem(value.packageManager); 14 | }); 15 | }; 16 | return PackageExplorerDirective; 17 | }()); 18 | exports.PackageExplorerDirective = PackageExplorerDirective; 19 | -------------------------------------------------------------------------------- /src/js/directives/ActivityBarDirective.ts: -------------------------------------------------------------------------------- 1 | import { PS_Packagest } from '../helpers/ConstantHelpers'; 2 | import { IPackagest } from "../interfaces/IPackagest"; 3 | 4 | export class ActivityBarDirective { 5 | restrict: string; 6 | templateUrl: string; 7 | transclude: boolean; 8 | 9 | constructor() { 10 | this.restrict = 'E' 11 | this.templateUrl = './templates/activity-bar.html' 12 | this.transclude = true 13 | } 14 | 15 | link(scope: any, element: any, attrs: any) { 16 | scope.$root.activityBarIcons = PS_Packagest; 17 | if (!scope.$$phase) scope.$apply(); 18 | 19 | scope.$root.activeActivityBarMenuItem = scope.$root.activityBarIcons[0]; 20 | scope.$root.startPackageExplorerWith = (item: IPackagest) => { 21 | scope.$root.activeActivityBarMenuItem = item; 22 | } 23 | 24 | scope.showSettingsDialog = () => { 25 | $('#settingsModal').modal('show'); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const electron = require('electron'); 2 | const { app, BrowserWindow } = electron; 3 | 4 | app.on('ready', onReady); 5 | 6 | function onReady() { 7 | let win = new BrowserWindow({ 8 | icon: `${__dirname}/images/app.ico`, 9 | }); 10 | win.maximize(); 11 | 12 | win.webContents.on('new-window', (event, url) => { 13 | event.preventDefault(); 14 | 15 | const { width, height } = electron.screen.getPrimaryDisplay().workAreaSize; 16 | 17 | const modalWin = new BrowserWindow({ 18 | icon: `${__dirname}/images/app.ico`, 19 | width: width * .9, 20 | height: height * .9, 21 | parent: win, 22 | modal: true, 23 | title: "The website is loading..." 24 | }); 25 | 26 | modalWin.setMenu(null); 27 | 28 | modalWin.once('ready-to-show', () => modalWin.show()); 29 | modalWin.loadURL(url); 30 | event.newGuest = modalWin; 31 | }) 32 | 33 | win.loadURL(`file://${__dirname}/index.html`); 34 | } -------------------------------------------------------------------------------- /js/directives/ActivityBarDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var ConstantHelpers_1 = require("../helpers/ConstantHelpers"); 4 | var ActivityBarDirective = (function () { 5 | function ActivityBarDirective() { 6 | this.restrict = 'E'; 7 | this.templateUrl = './templates/activity-bar.html'; 8 | this.transclude = true; 9 | } 10 | ActivityBarDirective.prototype.link = function (scope, element, attrs) { 11 | scope.$root.activityBarIcons = ConstantHelpers_1.PS_Packagest; 12 | if (!scope.$$phase) 13 | scope.$apply(); 14 | scope.$root.activeActivityBarMenuItem = scope.$root.activityBarIcons[0]; 15 | scope.$root.startPackageExplorerWith = function (item) { 16 | scope.$root.activeActivityBarMenuItem = item; 17 | }; 18 | scope.showSettingsDialog = function () { 19 | $('#settingsModal').modal('show'); 20 | }; 21 | }; 22 | return ActivityBarDirective; 23 | }()); 24 | exports.ActivityBarDirective = ActivityBarDirective; 25 | -------------------------------------------------------------------------------- /src/scss/_activity-bar.scss: -------------------------------------------------------------------------------- 1 | .workbench-container { 2 | activity-bar { 3 | .activity-bar-list { 4 | list-style: none; 5 | margin: 0; 6 | padding: 0; 7 | 8 | li { 9 | a { 10 | display: block; 11 | padding: 6px 8px; 12 | 13 | img { 14 | display: table-cell; 15 | vertical-align: middle; 16 | height: 40px; 17 | width: 32px; 18 | filter: grayscale(100%); 19 | } 20 | 21 | &.active { 22 | img { 23 | filter: grayscale(0); 24 | } 25 | } 26 | } 27 | } 28 | 29 | .settings-list-item { 30 | font-size: 20px; 31 | text-align: center; 32 | position: absolute; 33 | bottom: 24px; 34 | left: 6px; 35 | } 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Güray Yarar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | dist/ 38 | jspm_packages/ 39 | 40 | # Typescript v1 declaration files 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | 61 | -------------------------------------------------------------------------------- /js/helpers/ConstantHelpers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.LSKey_Package_Explorer_Width = 'Package_Explorer_Width'; 4 | exports.LSKey_Content_Split_LeftSide_Width = 'Content_Split_LeftSide_Width'; 5 | exports.LSKey_Package_Explorer_Packages = 'Package_Explorer_Packages'; 6 | exports.LSKey_Settings_Theme = 'Settings_Theme'; 7 | exports.Default_Package_Explorer_Width = 260; 8 | exports.Default_Content_Split_LeftSide_Width = 360; 9 | exports.Default_Settings_Theme = 'dark-theme'; 10 | exports.PS_Packagest = [ 11 | { 12 | title: 'NODEJS PACKAGE MANAGER (NPM)', 13 | packageManager: 'npm', 14 | file: 'package.json', 15 | isExistDevDependencies: true 16 | }, 17 | { 18 | title: 'BOWER', 19 | packageManager: 'bower', 20 | file: 'bower.json', 21 | isExistDevDependencies: false 22 | } 23 | ]; 24 | exports.appThemes = [ 25 | { 26 | name: "Dark Theme", 27 | class_name: "dark-theme", 28 | image: "dark-theme.jpg" 29 | }, 30 | { 31 | name: "Light Theme", 32 | class_name: "light-theme", 33 | image: "light-theme.jpg" 34 | } 35 | ]; 36 | -------------------------------------------------------------------------------- /src/js/helpers/ConstantHelpers.ts: -------------------------------------------------------------------------------- 1 | import { IPackagest } from '../interfaces/IPackagest'; 2 | 3 | //Localstorage Keys 4 | export const LSKey_Package_Explorer_Width: string = 'Package_Explorer_Width'; 5 | export const LSKey_Content_Split_LeftSide_Width: string = 'Content_Split_LeftSide_Width'; 6 | export const LSKey_Package_Explorer_Packages: string = 'Package_Explorer_Packages'; 7 | export const LSKey_Settings_Theme: string = 'Settings_Theme'; 8 | 9 | //Default Values 10 | export const Default_Package_Explorer_Width: number = 260; 11 | export const Default_Content_Split_LeftSide_Width: number = 360; 12 | export const Default_Settings_Theme: string = 'dark-theme'; 13 | 14 | //Program Support 15 | export const PS_Packagest: IPackagest[] = [ 16 | { 17 | title: 'NODEJS PACKAGE MANAGER (NPM)', 18 | packageManager: 'npm', 19 | file: 'package.json', 20 | isExistDevDependencies: true 21 | }, 22 | { 23 | title: 'BOWER', 24 | packageManager: 'bower', 25 | file: 'bower.json', 26 | isExistDevDependencies: false 27 | }]; 28 | 29 | //Themes 30 | export const appThemes: any = [ 31 | { 32 | name: "Dark Theme", 33 | class_name: "dark-theme", 34 | image: "dark-theme.jpg" 35 | }, 36 | { 37 | name: "Light Theme", 38 | class_name: "light-theme", 39 | image: "light-theme.jpg" 40 | }]; -------------------------------------------------------------------------------- /js/directives/PackageExplorerListItemDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var constantHelpers = require("../helpers/ConstantHelpers"); 4 | var PackageExplorerListDirective = (function () { 5 | function PackageExplorerListDirective() { 6 | this.restrict = 'E'; 7 | this.templateUrl = './templates/package-explorer-list.html'; 8 | this.transclude = true; 9 | this.scope = { 10 | item: '=item' 11 | }; 12 | } 13 | PackageExplorerListDirective.prototype.link = function (scope, element, attrs) { 14 | this.loadList(scope); 15 | scope.selectPackageExplorerItem = function (item) { 16 | scope.$root.activePackageExplorerItem = item; 17 | }; 18 | }; 19 | PackageExplorerListDirective.prototype.loadList = function (scope) { 20 | var packageManager = scope.item.packageManager; 21 | var packages = localStorage.getItem(constantHelpers.LSKey_Package_Explorer_Packages); 22 | var result = []; 23 | if (packageManager === 'npm') { 24 | result.push({ 25 | path: 'Global Packages', 26 | package_manager: 'npm' 27 | }); 28 | } 29 | scope.packagePathList = result; 30 | }; 31 | return PackageExplorerListDirective; 32 | }()); 33 | exports.PackageExplorerListDirective = PackageExplorerListDirective; 34 | -------------------------------------------------------------------------------- /src/js/helpers/StatusHelpers.ts: -------------------------------------------------------------------------------- 1 | export class StatusHelpers { 2 | setText(newText: string) { 3 | $('#status_text').html(newText); 4 | } 5 | 6 | setTextForPackageProcess(packageName: string, command: string, statu: string) { 7 | packageName = packageName.indexOf('||') !== -1 ? packageName.split('||')[0] : packageName; 8 | 9 | if (statu === 'start') { 10 | let processStartingText: string = 'installing'; 11 | if (command === 'update') processStartingText = 'updating'; 12 | if (command === 'downgrade') processStartingText = 'downgrading'; 13 | if (command === 'uninstall') processStartingText = 'uninstalling'; 14 | 15 | this.setText(`${packageName} ${processStartingText}...`); 16 | } else { 17 | let processEndText: string = 'installed'; 18 | if (command === 'update') processEndText = 'updated'; 19 | if (command === 'downgrade') processEndText = 'downgraded'; 20 | if (command === 'uninstall') processEndText = 'uninstalled'; 21 | 22 | this.setText(`${packageName} ${processEndText}`); 23 | //setTimeout(() => { this.reset(); }, 3200); 24 | } 25 | } 26 | 27 | getText() { 28 | $('#status_text').text(); 29 | } 30 | 31 | getTextAsHtml() { 32 | $('#status_text').html(); 33 | } 34 | 35 | reset() { 36 | $('#status_text').html(''); 37 | } 38 | } -------------------------------------------------------------------------------- /src/js/directives/PackageListItemDirective.ts: -------------------------------------------------------------------------------- 1 | import { IPackage } from '../interfaces/IPackage'; 2 | import { PackageHelpers } from '../helpers/PackageHelpers'; 3 | 4 | export class PackageListItemDirective { 5 | scope: any; 6 | restrict: string; 7 | templateUrl: string; 8 | transclude: boolean; 9 | 10 | constructor() { 11 | this.restrict = 'E' 12 | this.templateUrl = './templates/package-list-item.html' 13 | this.transclude = true 14 | this.scope = { 15 | item: '=item' 16 | } 17 | } 18 | 19 | link(scope: any, element: any, attrs: any) { 20 | const pack: IPackage = scope.item; 21 | 22 | if (pack.alreadyInstalled === true) { 23 | new PackageHelpers(scope).setLatestVersion(pack.name, pack.version, () => { 24 | this.organizeLoader(scope); 25 | }); 26 | } else { 27 | pack.latestVersion = pack.selectedVersion = pack.version; 28 | scope.item = pack; 29 | this.organizeLoader(scope); 30 | } 31 | 32 | scope.$root.selectPackage = ($event: any, item: any) => { 33 | if ($($event.target).hasClass('btn') === false && $($event.target).parents('.btn-group').length === 0) { 34 | scope.$root.activePackageItem = item; 35 | } 36 | } 37 | } 38 | 39 | organizeLoader(scope: any) { 40 | let length: number = scope.$root.loadedPackageLength; 41 | length--; 42 | scope.$root.loadedPackageLength = length; 43 | 44 | if (length === 0) scope.$root.showLoader = false; 45 | } 46 | } -------------------------------------------------------------------------------- /src/js/helpers/WindowHelpers.ts: -------------------------------------------------------------------------------- 1 | export class WindowHelpers { 2 | setPackageDetailContentHeight() { 3 | this.getPackageDetailContentHeight(); 4 | 5 | window.addEventListener('resize', (e) => { 6 | e.preventDefault(); 7 | this.getPackageDetailContentHeight(); 8 | }); 9 | 10 | $.each($('.package-detail-container .tab-content .tab-pane'), (i: number, value: any) => { 11 | this.initScrollToTop(value); 12 | }) 13 | } 14 | 15 | initScrollToTop(element: any) { 16 | let $el: any = $(element); 17 | let $scrollTop: any; 18 | 19 | if ($el.find('.scroll-to-top').length === 0) { 20 | $scrollTop = $(''); 21 | $scrollTop.hide(); 22 | $el.append($scrollTop); 23 | } 24 | 25 | $('.package-detail-container .tab-content .tab-pane').on('click', '.scroll-to-top', () => { 26 | if ($el.hasClass('active')) $el.animate({ scrollTop: 0 }, 'slow'); 27 | }); 28 | 29 | $el.scroll(() => { 30 | if ($el.scrollTop() > 240) { $el.find('.scroll-to-top').fadeIn(); } else { $el.find('.scroll-to-top').fadeOut(); } 31 | }); 32 | } 33 | 34 | private getPackageDetailContentHeight() { 35 | const height: number = $('body').height() - ($('.package-detail-container .header').innerHeight() + $('footer').innerHeight() + $('.package-detail-container .nav-tabs').innerHeight()) - 31; 36 | $('.package-detail-info-container .tab-content .tab-pane').height(height); 37 | } 38 | } -------------------------------------------------------------------------------- /src/scss/_helpers.scss: -------------------------------------------------------------------------------- 1 | //Margin 2 | @for $i from -25 through 25 { 3 | .m-l-#{$i * 5} { 4 | margin-left: #{$i * 5}px; 5 | } 6 | 7 | .m-t-#{$i * 5} { 8 | margin-top: #{$i * 5}px; 9 | } 10 | 11 | .m-r-#{$i * 5} { 12 | margin-right: #{$i * 5}px; 13 | } 14 | 15 | .m-b-#{$i * 5} { 16 | margin-bottom: #{$i * 5}px; 17 | } 18 | } 19 | 20 | @for $i from 0 through 25 { 21 | .margin-#{$i * 5} { 22 | margin: #{$i * 5}; 23 | } 24 | 25 | .padding-#{$i * 5} { 26 | padding: #{$i * 5}px; 27 | } 28 | } 29 | 30 | @for $i from 0 through 25 { 31 | .p-l-#{$i * 5} { 32 | padding-left: #{$i * 5}px; 33 | } 34 | 35 | .p-t-#{$i * 5} { 36 | padding-top: #{$i * 5}px; 37 | } 38 | 39 | .p-r-#{$i * 5} { 40 | padding-right: #{$i * 5}px; 41 | } 42 | 43 | .p-b-#{$i * 5} { 44 | padding-bottom: #{$i * 5}px; 45 | } 46 | 47 | .padding-#{$i * 5} { 48 | padding: #{$i * 5}px; 49 | } 50 | } 51 | 52 | @for $i from 5 through 49 { 53 | .font-#{$i + 1} { 54 | font-size: #{$i + 1}px; 55 | } 56 | } 57 | 58 | .align-left { 59 | text-align: left; 60 | } 61 | 62 | .align-center { 63 | text-align: center; 64 | } 65 | 66 | .align-right { 67 | text-align: right; 68 | } 69 | 70 | .align-justify { 71 | text-align: justify; 72 | } 73 | 74 | .no-resize { 75 | resize: none; 76 | } 77 | 78 | .font-bold { 79 | font-weight: bold; 80 | } 81 | 82 | .font-italic { 83 | font-style: italic; 84 | } 85 | 86 | .font-underline { 87 | text-decoration: underline; 88 | } 89 | 90 | .font-line-through { 91 | text-decoration: line-through; 92 | } 93 | 94 | .font-overline { 95 | text-decoration: overline; 96 | } -------------------------------------------------------------------------------- /js/directives/PackageListItemDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var PackageHelpers_1 = require("../helpers/PackageHelpers"); 4 | var PackageListItemDirective = (function () { 5 | function PackageListItemDirective() { 6 | this.restrict = 'E'; 7 | this.templateUrl = './templates/package-list-item.html'; 8 | this.transclude = true; 9 | this.scope = { 10 | item: '=item' 11 | }; 12 | } 13 | PackageListItemDirective.prototype.link = function (scope, element, attrs) { 14 | var _this = this; 15 | var pack = scope.item; 16 | if (pack.alreadyInstalled === true) { 17 | new PackageHelpers_1.PackageHelpers(scope).setLatestVersion(pack.name, pack.version, function () { 18 | _this.organizeLoader(scope); 19 | }); 20 | } 21 | else { 22 | pack.latestVersion = pack.selectedVersion = pack.version; 23 | scope.item = pack; 24 | this.organizeLoader(scope); 25 | } 26 | scope.$root.selectPackage = function ($event, item) { 27 | if ($($event.target).hasClass('btn') === false && $($event.target).parents('.btn-group').length === 0) { 28 | scope.$root.activePackageItem = item; 29 | } 30 | }; 31 | }; 32 | PackageListItemDirective.prototype.organizeLoader = function (scope) { 33 | var length = scope.$root.loadedPackageLength; 34 | length--; 35 | scope.$root.loadedPackageLength = length; 36 | if (length === 0) 37 | scope.$root.showLoader = false; 38 | }; 39 | return PackageListItemDirective; 40 | }()); 41 | exports.PackageListItemDirective = PackageListItemDirective; 42 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | NodeJs Package Manager 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 |
25 |
26 | 27 |
28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 | 36 | 37 | 38 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /js/helpers/StatusHelpers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var StatusHelpers = (function () { 4 | function StatusHelpers() { 5 | } 6 | StatusHelpers.prototype.setText = function (newText) { 7 | $('#status_text').html(newText); 8 | }; 9 | StatusHelpers.prototype.setTextForPackageProcess = function (packageName, command, statu) { 10 | packageName = packageName.indexOf('||') !== -1 ? packageName.split('||')[0] : packageName; 11 | if (statu === 'start') { 12 | var processStartingText = 'installing'; 13 | if (command === 'update') 14 | processStartingText = 'updating'; 15 | if (command === 'downgrade') 16 | processStartingText = 'downgrading'; 17 | if (command === 'uninstall') 18 | processStartingText = 'uninstalling'; 19 | this.setText("" + packageName + " " + processStartingText + "..."); 20 | } 21 | else { 22 | var processEndText = 'installed'; 23 | if (command === 'update') 24 | processEndText = 'updated'; 25 | if (command === 'downgrade') 26 | processEndText = 'downgraded'; 27 | if (command === 'uninstall') 28 | processEndText = 'uninstalled'; 29 | this.setText("" + packageName + " " + processEndText); 30 | } 31 | }; 32 | StatusHelpers.prototype.getText = function () { 33 | $('#status_text').text(); 34 | }; 35 | StatusHelpers.prototype.getTextAsHtml = function () { 36 | $('#status_text').html(); 37 | }; 38 | StatusHelpers.prototype.reset = function () { 39 | $('#status_text').html(''); 40 | }; 41 | return StatusHelpers; 42 | }()); 43 | exports.StatusHelpers = StatusHelpers; 44 | -------------------------------------------------------------------------------- /src/js/helpers/MessageDialogHelpers.ts: -------------------------------------------------------------------------------- 1 | const Noty = require('noty'); 2 | 3 | export class MessageDialogHelpers { 4 | error(msg: string, timeout?: number, position: string = 'topCenter') { 5 | let options = { 6 | text: msg, 7 | type: 'error', 8 | layout: position, 9 | animation: { 10 | open: 'animated fadeInDown', 11 | close: 'animated fadeOutUp' 12 | } 13 | }; 14 | 15 | if (timeout !== null) { 16 | options.timeout = timeout; 17 | } 18 | new Noty(options).show(); 19 | } 20 | 21 | success(msg: string, timeout?: number, position: string = 'topCenter') { 22 | let options = { 23 | text: msg, 24 | type: 'success', 25 | layout: position, 26 | animation: { 27 | open: 'animated fadeInDown', 28 | close: 'animated fadeOutUp' 29 | } 30 | }; 31 | 32 | if (timeout !== null) { 33 | options.timeout = timeout; 34 | } 35 | new Noty(options).show(); 36 | } 37 | 38 | confirm(msg: string, callback: any) { 39 | var n = new Noty({ 40 | text: msg, 41 | type: 'alert', 42 | layout: 'center', 43 | modal: true, 44 | animation: { 45 | open: 'animated fadeInDown', 46 | close: 'animated fadeOutUp' 47 | }, 48 | buttons: [ 49 | Noty.button('Yes, please', 'btn btn-success m-r-10', () => { 50 | callback(); 51 | n.close(); 52 | }), 53 | 54 | Noty.button('No', 'btn btn-default', () => { 55 | n.close(); 56 | }) 57 | ] 58 | }).show(); 59 | } 60 | } -------------------------------------------------------------------------------- /src/scss/_settings.scss: -------------------------------------------------------------------------------- 1 | #settingsModal { 2 | .tab-content { 3 | .theme-list { 4 | list-style: none; 5 | margin: 0; 6 | padding: 0; 7 | 8 | > li { 9 | display: inline-block; 10 | 11 | &:first-child { 12 | margin-right: 15px; 13 | } 14 | 15 | > a { 16 | text-decoration: none; 17 | font-size: 13px; 18 | 19 | > label { 20 | display: block; 21 | font-weight: normal; 22 | margin-top: 10px; 23 | cursor: pointer; 24 | } 25 | } 26 | } 27 | } 28 | 29 | .about-panel { 30 | img { 31 | max-width: 128px; 32 | } 33 | 34 | h1 { 35 | font-size: 19px; 36 | text-align: center; 37 | 38 | sup { 39 | font-size: 11px; 40 | font-weight: bold; 41 | } 42 | } 43 | 44 | .description { 45 | font-size: 13px; 46 | text-align: center; 47 | } 48 | 49 | .author-name { 50 | margin-top: 25px; 51 | font-size: 13px; 52 | 53 | a { 54 | font-weight: bold; 55 | } 56 | } 57 | 58 | .project-links { 59 | margin-top: 7px; 60 | margin-bottom: 5px; 61 | 62 | a:not(.btn) { 63 | display: table; 64 | font-weight: bold; 65 | font-size: 13px; 66 | line-height: 21px; 67 | } 68 | } 69 | } 70 | } 71 | } -------------------------------------------------------------------------------- /templates/package-explorer-list.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 | 6 | 12 |
13 |
14 |
15 | 16 |
-- No Package File --
17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodejs-package-manager", 3 | "version": "0.1.0", 4 | "description": "npm, bower package manager", 5 | "author": "Güray Yarar", 6 | "license": "MIT", 7 | "scripts": { 8 | "start": "gulp default | electron .", 9 | "dist": "build", 10 | "test": "echo \"Error: no test specified\" && exit 1" 11 | }, 12 | "dependencies": { 13 | "@shagstrom/split-pane": "^0.9.4", 14 | "@types/angular": "^1.6.27", 15 | "@types/bootstrap": "^3.3.35", 16 | "@types/jquery": "^3.2.9", 17 | "angular": "^1.7.9", 18 | "angular-sanitize": "^1.6.5", 19 | "animate.css": "^3.5.2", 20 | "bootstrap": "^3.3.7", 21 | "bower": "^1.8.0", 22 | "compare-versions": "^3.0.1", 23 | "font-awesome": "^4.7.0", 24 | "get-package-readme": "^1.2.0", 25 | "jquery": "^3.4.0", 26 | "noty": "^3.1.1", 27 | "q": "^1.5.0", 28 | "showdown": "^1.7.1", 29 | "underscore": "^1.8.3" 30 | }, 31 | "devDependencies": { 32 | "electron": "^4.1.0", 33 | "electron-builder": "^20.39.0", 34 | "gulp-sass": "^4.0.2" 35 | }, 36 | "build": { 37 | "appId": "com.gurayyarar.nodejspackagemanager", 38 | "productName": "NodeJs Package Manager", 39 | "asar": false, 40 | "extraResources": [ 41 | { 42 | "from": "node_modules/bower/lib/node_modules", 43 | "to": "app/node_modules/bower/lib/node_modules" 44 | } 45 | ], 46 | "nsis": { 47 | "oneClick": true, 48 | "createDesktopShortcut": true, 49 | "allowElevation": false, 50 | "language": "1033" 51 | }, 52 | "win": { 53 | "publisherName": "Güray Yarar", 54 | "target": "nsis", 55 | "icon": "images/app.ico" 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /js/helpers/WindowHelpers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var WindowHelpers = (function () { 4 | function WindowHelpers() { 5 | } 6 | WindowHelpers.prototype.setPackageDetailContentHeight = function () { 7 | var _this = this; 8 | this.getPackageDetailContentHeight(); 9 | window.addEventListener('resize', function (e) { 10 | e.preventDefault(); 11 | _this.getPackageDetailContentHeight(); 12 | }); 13 | $.each($('.package-detail-container .tab-content .tab-pane'), function (i, value) { 14 | _this.initScrollToTop(value); 15 | }); 16 | }; 17 | WindowHelpers.prototype.initScrollToTop = function (element) { 18 | var $el = $(element); 19 | var $scrollTop; 20 | if ($el.find('.scroll-to-top').length === 0) { 21 | $scrollTop = $(''); 22 | $scrollTop.hide(); 23 | $el.append($scrollTop); 24 | } 25 | $('.package-detail-container .tab-content .tab-pane').on('click', '.scroll-to-top', function () { 26 | if ($el.hasClass('active')) 27 | $el.animate({ scrollTop: 0 }, 'slow'); 28 | }); 29 | $el.scroll(function () { 30 | if ($el.scrollTop() > 240) { 31 | $el.find('.scroll-to-top').fadeIn(); 32 | } 33 | else { 34 | $el.find('.scroll-to-top').fadeOut(); 35 | } 36 | }); 37 | }; 38 | WindowHelpers.prototype.getPackageDetailContentHeight = function () { 39 | var height = $('body').height() - ($('.package-detail-container .header').innerHeight() + $('footer').innerHeight() + $('.package-detail-container .nav-tabs').innerHeight()) - 31; 40 | $('.package-detail-info-container .tab-content .tab-pane').height(height); 41 | }; 42 | return WindowHelpers; 43 | }()); 44 | exports.WindowHelpers = WindowHelpers; 45 | -------------------------------------------------------------------------------- /src/js/controller/MainController.ts: -------------------------------------------------------------------------------- 1 | import * as constantHelpers from '../helpers/ConstantHelpers'; 2 | 3 | export class MainController { 4 | $scope: any; 5 | 6 | constructor($scope: any) { 7 | this.$scope = $scope; 8 | 9 | this.setSplitPanel(); 10 | } 11 | 12 | setSplitPanel() { 13 | const packageExplorerWidth: string = localStorage.getItem(constantHelpers.LSKey_Package_Explorer_Width) || constantHelpers.Default_Package_Explorer_Width.toString(); 14 | const packageContentWidth: string = localStorage.getItem(constantHelpers.LSKey_Content_Split_LeftSide_Width) || constantHelpers.Default_Content_Split_LeftSide_Width.toString(); 15 | 16 | this.$scope.$root.packageExplorerStyle = { 'width': `${packageExplorerWidth}px` }; 17 | this.$scope.$root.contentSplitStyle = { 'width': `${packageContentWidth}px` }; 18 | 19 | this.$scope.$root.packageExplorerDividerAndRightSideStyle = { 'left': `${packageExplorerWidth}px` }; 20 | this.$scope.$root.contentDividerAndRightSideStyle = { 'left': `${packageContentWidth}px` } 21 | 22 | $('.main-split-pane').splitPane(); 23 | 24 | $('.main-split-pane .split-pane-divider').on('mousedown', function () { 25 | var $this = $(this); 26 | $('body').one('mouseup', function () { 27 | const outerWidth: number = $this.prev().outerWidth(); 28 | localStorage.setItem(constantHelpers.LSKey_Package_Explorer_Width, outerWidth.toString()); 29 | }); 30 | }); 31 | 32 | setTimeout(() => { 33 | $('.content-split-pane').splitPane(); 34 | $('.content-split-pane .split-pane-divider').on('mousedown', function () { 35 | var $this = $(this); 36 | $('body').one('mouseup', function () { 37 | const outerWidth: number = $this.prev().outerWidth(); 38 | localStorage.setItem(constantHelpers.LSKey_Content_Split_LeftSide_Width, outerWidth.toString()); 39 | }); 40 | }); 41 | }, 1250); 42 | } 43 | } -------------------------------------------------------------------------------- /src/js/app.ts: -------------------------------------------------------------------------------- 1 | import * as angular from 'angular'; 2 | global.$ = global.jQuery = require('jquery'); 3 | global._ = require('underscore'); 4 | import { MainController } from './controller/MainController'; 5 | import { ActivityBarDirective } from './directives/ActivityBarDirective'; 6 | import { PackageExplorerDirective } from './directives/PackageExplorerDirective'; 7 | import { PackageExplorerListDirective } from './directives/PackageExplorerListDirective'; 8 | import { FooterDirective } from './directives/FooterDirective'; 9 | import { PackageDirective } from './directives/PackageDirective'; 10 | import { PackageListDirective } from './directives/PackageListDirective'; 11 | import { PackageListItemDirective } from './directives/PackageListItemDirective'; 12 | import { LoaderDirective } from './directives/LoaderDirective'; 13 | import { PackageInitDirective } from './directives/PackageInitDirective'; 14 | import { PackageDetail } from './directives/PackageDetailDirective'; 15 | import { SettingsDirective } from './directives/SettingsDirective'; 16 | require('@shagstrom/split-pane'); 17 | require('bootstrap'); 18 | 19 | 20 | angular.module('app', [require('angular-sanitize')]) 21 | .controller('MainController', MainController) 22 | 23 | .directive('activityBar', () => new ActivityBarDirective()) 24 | .directive('packageExplorer', () => new PackageExplorerDirective()) 25 | .directive('packageExplorerList', () => new PackageExplorerListDirective()) 26 | .directive('footer', () => new FooterDirective()) 27 | .directive('packages', () => new PackageDirective()) 28 | .directive('packageList', () => new PackageListDirective()) 29 | .directive('packageListItem', () => new PackageListItemDirective()) 30 | .directive('loader', () => new LoaderDirective()) 31 | .directive('packageInit', () => new PackageInitDirective()) 32 | .directive('packageDetail', () => new PackageDetail()) 33 | .directive('settings', () => new SettingsDirective()) 34 | 35 | $(() => { 36 | $('.modal').on('click', '.advanced-options a', (e) => { 37 | $(e.target).parents('.advanced-options').toggleClass('open'); 38 | }); 39 | }) -------------------------------------------------------------------------------- /js/controller/MainController.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var constantHelpers = require("../helpers/ConstantHelpers"); 4 | var MainController = (function () { 5 | function MainController($scope) { 6 | this.$scope = $scope; 7 | this.setSplitPanel(); 8 | } 9 | MainController.prototype.setSplitPanel = function () { 10 | var packageExplorerWidth = localStorage.getItem(constantHelpers.LSKey_Package_Explorer_Width) || constantHelpers.Default_Package_Explorer_Width.toString(); 11 | var packageContentWidth = localStorage.getItem(constantHelpers.LSKey_Content_Split_LeftSide_Width) || constantHelpers.Default_Content_Split_LeftSide_Width.toString(); 12 | this.$scope.$root.packageExplorerStyle = { 'width': packageExplorerWidth + "px" }; 13 | this.$scope.$root.contentSplitStyle = { 'width': packageContentWidth + "px" }; 14 | this.$scope.$root.packageExplorerDividerAndRightSideStyle = { 'left': packageExplorerWidth + "px" }; 15 | this.$scope.$root.contentDividerAndRightSideStyle = { 'left': packageContentWidth + "px" }; 16 | $('.main-split-pane').splitPane(); 17 | $('.main-split-pane .split-pane-divider').on('mousedown', function () { 18 | var $this = $(this); 19 | $('body').one('mouseup', function () { 20 | var outerWidth = $this.prev().outerWidth(); 21 | localStorage.setItem(constantHelpers.LSKey_Package_Explorer_Width, outerWidth.toString()); 22 | }); 23 | }); 24 | setTimeout(function () { 25 | $('.content-split-pane').splitPane(); 26 | $('.content-split-pane .split-pane-divider').on('mousedown', function () { 27 | var $this = $(this); 28 | $('body').one('mouseup', function () { 29 | var outerWidth = $this.prev().outerWidth(); 30 | localStorage.setItem(constantHelpers.LSKey_Content_Split_LeftSide_Width, outerWidth.toString()); 31 | }); 32 | }); 33 | }, 1250); 34 | }; 35 | return MainController; 36 | }()); 37 | exports.MainController = MainController; 38 | -------------------------------------------------------------------------------- /js/helpers/MessageDialogHelpers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var Noty = require('noty'); 4 | var MessageDialogHelpers = (function () { 5 | function MessageDialogHelpers() { 6 | } 7 | MessageDialogHelpers.prototype.error = function (msg, timeout, position) { 8 | if (position === void 0) { position = 'topCenter'; } 9 | var options = { 10 | text: msg, 11 | type: 'error', 12 | layout: position, 13 | animation: { 14 | open: 'animated fadeInDown', 15 | close: 'animated fadeOutUp' 16 | } 17 | }; 18 | if (timeout !== null) { 19 | options.timeout = timeout; 20 | } 21 | new Noty(options).show(); 22 | }; 23 | MessageDialogHelpers.prototype.success = function (msg, timeout, position) { 24 | if (position === void 0) { position = 'topCenter'; } 25 | var options = { 26 | text: msg, 27 | type: 'success', 28 | layout: position, 29 | animation: { 30 | open: 'animated fadeInDown', 31 | close: 'animated fadeOutUp' 32 | } 33 | }; 34 | if (timeout !== null) { 35 | options.timeout = timeout; 36 | } 37 | new Noty(options).show(); 38 | }; 39 | MessageDialogHelpers.prototype.confirm = function (msg, callback) { 40 | var n = new Noty({ 41 | text: msg, 42 | type: 'alert', 43 | layout: 'center', 44 | modal: true, 45 | animation: { 46 | open: 'animated fadeInDown', 47 | close: 'animated fadeOutUp' 48 | }, 49 | buttons: [ 50 | Noty.button('Yes, please', 'btn btn-success m-r-10', function () { 51 | callback(); 52 | n.close(); 53 | }), 54 | Noty.button('No', 'btn btn-default', function () { 55 | n.close(); 56 | }) 57 | ] 58 | }).show(); 59 | }; 60 | return MessageDialogHelpers; 61 | }()); 62 | exports.MessageDialogHelpers = MessageDialogHelpers; 63 | -------------------------------------------------------------------------------- /js/directives/SettingsDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var constantHelpers = require("../helpers/ConstantHelpers"); 4 | var remote = require('electron').remote; 5 | var shell = require('electron').shell; 6 | var SettingsDirective = (function () { 7 | function SettingsDirective() { 8 | this.restrict = 'E'; 9 | this.templateUrl = './templates/settings.html'; 10 | this.transclude = true; 11 | } 12 | SettingsDirective.prototype.link = function (scope, element, attrs) { 13 | var themes = constantHelpers.appThemes; 14 | var selectedTheme = localStorage.getItem(constantHelpers.LSKey_Settings_Theme); 15 | scope.themes = themes; 16 | $('body').addClass((selectedTheme === undefined || selectedTheme === null ? constantHelpers.Default_Settings_Theme : selectedTheme)); 17 | scope.selectedTheme = $.grep(themes, function (key, i) { 18 | return key.class_name.toString() === (selectedTheme === undefined || selectedTheme === null ? constantHelpers.Default_Settings_Theme : selectedTheme); 19 | })[0]; 20 | $('.about-panel a, #settingsModal .js-donation-btn').on('click', function (e) { 21 | e.preventDefault(); 22 | shell.openExternal($(e.target).attr('href')); 23 | }); 24 | $('#settingsModal .nav-tabs a').on('click', function (e) { 25 | scope.showDonationBtn = $(e.target).attr('href') === '#about'; 26 | if (!scope.$$phase) 27 | scope.$apply(); 28 | }); 29 | scope.changeTheme = function (item) { 30 | var classes = $('body').attr('class').split(' '); 31 | classes.forEach(function (val, i) { 32 | if (val.indexOf('-theme') > -1) 33 | $('body').removeClass(val); 34 | }); 35 | $('body').addClass(item.class_name); 36 | scope.selectedTheme = item; 37 | localStorage.setItem(constantHelpers.LSKey_Settings_Theme, item.class_name); 38 | }; 39 | scope.restoreToDefaults = function () { 40 | var packages = localStorage.getItem(constantHelpers.LSKey_Package_Explorer_Packages); 41 | localStorage.clear(); 42 | localStorage.setItem(constantHelpers.LSKey_Package_Explorer_Packages, packages); 43 | remote.getCurrentWindow().reload(); 44 | }; 45 | }; 46 | return SettingsDirective; 47 | }()); 48 | exports.SettingsDirective = SettingsDirective; 49 | -------------------------------------------------------------------------------- /templates/packages.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 |
7 |
8 | PACKAGES 9 | 22 |
23 |
24 |
25 | 27 | 28 |
29 |
30 | 31 |
32 |
33 |
34 |
35 | 36 |
37 |
38 |
39 |
-------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var angular = require("angular"); 4 | global.$ = global.jQuery = require('jquery'); 5 | global._ = require('underscore'); 6 | var MainController_1 = require("./controller/MainController"); 7 | var ActivityBarDirective_1 = require("./directives/ActivityBarDirective"); 8 | var PackageExplorerDirective_1 = require("./directives/PackageExplorerDirective"); 9 | var PackageExplorerListDirective_1 = require("./directives/PackageExplorerListDirective"); 10 | var FooterDirective_1 = require("./directives/FooterDirective"); 11 | var PackageDirective_1 = require("./directives/PackageDirective"); 12 | var PackageListDirective_1 = require("./directives/PackageListDirective"); 13 | var PackageListItemDirective_1 = require("./directives/PackageListItemDirective"); 14 | var LoaderDirective_1 = require("./directives/LoaderDirective"); 15 | var PackageInitDirective_1 = require("./directives/PackageInitDirective"); 16 | var PackageDetailDirective_1 = require("./directives/PackageDetailDirective"); 17 | var SettingsDirective_1 = require("./directives/SettingsDirective"); 18 | require('@shagstrom/split-pane'); 19 | require('bootstrap'); 20 | angular.module('app', [require('angular-sanitize')]) 21 | .controller('MainController', MainController_1.MainController) 22 | .directive('activityBar', function () { return new ActivityBarDirective_1.ActivityBarDirective(); }) 23 | .directive('packageExplorer', function () { return new PackageExplorerDirective_1.PackageExplorerDirective(); }) 24 | .directive('packageExplorerList', function () { return new PackageExplorerListDirective_1.PackageExplorerListDirective(); }) 25 | .directive('footer', function () { return new FooterDirective_1.FooterDirective(); }) 26 | .directive('packages', function () { return new PackageDirective_1.PackageDirective(); }) 27 | .directive('packageList', function () { return new PackageListDirective_1.PackageListDirective(); }) 28 | .directive('packageListItem', function () { return new PackageListItemDirective_1.PackageListItemDirective(); }) 29 | .directive('loader', function () { return new LoaderDirective_1.LoaderDirective(); }) 30 | .directive('packageInit', function () { return new PackageInitDirective_1.PackageInitDirective(); }) 31 | .directive('packageDetail', function () { return new PackageDetailDirective_1.PackageDetail(); }) 32 | .directive('settings', function () { return new SettingsDirective_1.SettingsDirective(); }); 33 | $(function () { 34 | $('.modal').on('click', '.advanced-options a', function (e) { 35 | $(e.target).parents('.advanced-options').toggleClass('open'); 36 | }); 37 | }); 38 | -------------------------------------------------------------------------------- /src/js/helpers/PackageExplorerHelpers.ts: -------------------------------------------------------------------------------- 1 | import { IPackageExplorer } from '../interfaces/IPackageExplorer'; 2 | import { LSKey_Package_Explorer_Packages, PS_Packagest } from './ConstantHelpers'; 3 | 4 | export class PackageExplorerHelpers { 5 | getListItem(packageManager: string): IPackageExplorer[] { 6 | const packs: IPackageExplorer[] = this.getAllItems(); 7 | 8 | let result: IPackageExplorer[] = $.grep(packs, (key, i) => { 9 | return key.packageManager === packageManager; 10 | }); 11 | 12 | if (packageManager === 'npm') { 13 | result.push({ 14 | caption: 'Global Packages', 15 | path: null, 16 | packageManager: packageManager, 17 | canDelete: false, 18 | isExistDevDependencies: false 19 | }); 20 | } 21 | 22 | return result.reverse(); 23 | } 24 | 25 | add(packageManager: string, path: string) { 26 | let packs: IPackageExplorer[] = this.getAllItems(); 27 | 28 | packs.push({ 29 | caption: path, 30 | canDelete: true, 31 | packageManager: packageManager, 32 | path: path, 33 | isExistDevDependencies: $.grep(PS_Packagest, (val: any, i: number) => { 34 | return val.packageManager === packageManager; 35 | })[0].isExistDevDependencies 36 | }); 37 | 38 | localStorage.setItem(LSKey_Package_Explorer_Packages, JSON.stringify(packs)); 39 | } 40 | 41 | remove(path: string) { 42 | const packs: IPackageExplorer[] = this.getAllItems(); 43 | 44 | let result: IPackageExplorer[] = $.grep(packs, (key, i) => { 45 | return key.path !== path; 46 | }); 47 | 48 | localStorage.setItem(LSKey_Package_Explorer_Packages, JSON.stringify(result)); 49 | } 50 | 51 | removeAllList(packageManager: string) { 52 | const packs: IPackageExplorer[] = this.getAllItems(); 53 | 54 | let result: IPackageExplorer[] = $.grep(packs, (key, i) => { 55 | return key.packageManager !== packageManager; 56 | }); 57 | 58 | localStorage.setItem(LSKey_Package_Explorer_Packages, JSON.stringify(result)); 59 | } 60 | 61 | isExist(path: string): boolean { 62 | const packs: IPackageExplorer[] = this.getAllItems(); 63 | 64 | return $.grep(packs, (key, i) => { 65 | return key.path === path 66 | }).length > 0; 67 | } 68 | 69 | private getAllItems(): IPackageExplorer[] { 70 | let packs: string = localStorage.getItem(LSKey_Package_Explorer_Packages); 71 | return packs === null ? [] : JSON.parse(packs); 72 | } 73 | } -------------------------------------------------------------------------------- /src/js/directives/SettingsDirective.ts: -------------------------------------------------------------------------------- 1 | import * as constantHelpers from '../helpers/ConstantHelpers'; 2 | import { Default_Settings_Theme } from '../helpers/ConstantHelpers'; 3 | const remote = require('electron').remote; 4 | const shell = require('electron').shell; 5 | 6 | export class SettingsDirective { 7 | restrict: string; 8 | templateUrl: string; 9 | transclude: boolean; 10 | 11 | constructor() { 12 | this.restrict = 'E' 13 | this.templateUrl = './templates/settings.html' 14 | this.transclude = true 15 | } 16 | 17 | link(scope: any, element: any, attrs: any) { 18 | let themes: any = constantHelpers.appThemes; 19 | const selectedTheme: string = localStorage.getItem(constantHelpers.LSKey_Settings_Theme); 20 | scope.themes = themes; 21 | $('body').addClass((selectedTheme === undefined || selectedTheme === null ? constantHelpers.Default_Settings_Theme : selectedTheme)); 22 | 23 | //Selected theme assigning 24 | scope.selectedTheme = $.grep(themes, (key: any, i: number) => { 25 | return key.class_name.toString() === (selectedTheme === undefined || selectedTheme === null ? constantHelpers.Default_Settings_Theme : selectedTheme); 26 | })[0]; 27 | 28 | //When a link & donation button click inside of the About Tab (will open the defalt web browser) 29 | $('.about-panel a, #settingsModal .js-donation-btn').on('click', (e) => { 30 | e.preventDefault(); 31 | shell.openExternal($(e.target).attr('href')); 32 | }); 33 | 34 | //Navtabs item click inside of the Settings Modal Dialog 35 | $('#settingsModal .nav-tabs a').on('click', (e) => { 36 | scope.showDonationBtn = $(e.target).attr('href') === '#about'; 37 | if (!scope.$$phase) scope.$apply(); 38 | }); 39 | 40 | //Change application theme 41 | scope.changeTheme = (item: any) => { 42 | const classes: any = $('body').attr('class').split(' '); 43 | classes.forEach((val: any, i: number) => { 44 | if (val.indexOf('-theme') > -1) $('body').removeClass(val); 45 | }); 46 | 47 | $('body').addClass(item.class_name); 48 | 49 | scope.selectedTheme = item; 50 | localStorage.setItem(constantHelpers.LSKey_Settings_Theme, item.class_name); 51 | } 52 | 53 | //Restore settings to default values 54 | scope.restoreToDefaults = () => { 55 | const packages: any = localStorage.getItem(constantHelpers.LSKey_Package_Explorer_Packages); 56 | localStorage.clear(); 57 | 58 | localStorage.setItem(constantHelpers.LSKey_Package_Explorer_Packages, packages); 59 | remote.getCurrentWindow().reload(); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/js/directives/PackageListDirective.ts: -------------------------------------------------------------------------------- 1 | import { PackageHelpers } from '../helpers/PackageHelpers'; 2 | import { IPackageExplorer } from '../interfaces/IPackageExplorer'; 3 | import { MessageDialogHelpers } from '../helpers/MessageDialogHelpers'; 4 | import { IPackagest } from '../interfaces/IPackagest'; 5 | import { PackageExplorerHelpers } from '../helpers/PackageExplorerHelpers'; 6 | import { PackageInitFileHelpers } from '../helpers/PackageInitFileHelpers'; 7 | const fs = require('fs'); 8 | const remote = require('electron').remote; 9 | const shell = remote.shell; 10 | 11 | export class PackageListDirective { 12 | restrict: string; 13 | templateUrl: string; 14 | transclude: boolean; 15 | 16 | constructor() { 17 | this.restrict = 'E' 18 | this.templateUrl = './templates/package-list.html' 19 | this.transclude = true 20 | } 21 | 22 | link(scope: any, element: any, attrs: any) { 23 | scope.$root.$watch('activePackageExplorerItem', (newVal: any, oldVal: any) => { 24 | if (newVal !== undefined) { 25 | scope.$root.showLoader = true; 26 | 27 | if (newVal.path !== undefined && newVal.path !== null) { 28 | fs.access(newVal.path, (err: any) => { 29 | if (err) { 30 | new MessageDialogHelpers().confirm('The file does not exist!
Do you want to remove item from list?', () => { 31 | const activeItem: IPackagest = scope.$root.activeActivityBarMenuItem; 32 | new PackageExplorerHelpers().remove(newVal.path); 33 | scope.$apply(() => { 34 | scope.$root.packagePathList[activeItem.packageManager] = new PackageExplorerHelpers().getListItem(activeItem.packageManager); 35 | scope.$root.showLoader = false; 36 | }); 37 | }); 38 | } else { 39 | scope.$root.hidePackageOverlay = false; 40 | scope.$root.hidePackageDetailOverlay = false; 41 | scope.$root.searchVal = ''; 42 | scope.$root.reloadPackageList(); 43 | if (!scope.$$phase) scope.$apply(); 44 | } 45 | }); 46 | } else { 47 | scope.$root.hidePackageOverlay = false; 48 | scope.$root.hidePackageDetailOverlay = false; 49 | scope.$root.searchVal = ''; 50 | scope.$root.reloadPackageList(); 51 | if (!scope.$$phase) scope.$apply(); 52 | } 53 | }; 54 | }); 55 | } 56 | } -------------------------------------------------------------------------------- /js/helpers/PackageExplorerHelpers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var ConstantHelpers_1 = require("./ConstantHelpers"); 4 | var PackageExplorerHelpers = (function () { 5 | function PackageExplorerHelpers() { 6 | } 7 | PackageExplorerHelpers.prototype.getListItem = function (packageManager) { 8 | var packs = this.getAllItems(); 9 | var result = $.grep(packs, function (key, i) { 10 | return key.packageManager === packageManager; 11 | }); 12 | if (packageManager === 'npm') { 13 | result.push({ 14 | caption: 'Global Packages', 15 | path: null, 16 | packageManager: packageManager, 17 | canDelete: false, 18 | isExistDevDependencies: false 19 | }); 20 | } 21 | return result.reverse(); 22 | }; 23 | PackageExplorerHelpers.prototype.add = function (packageManager, path) { 24 | var packs = this.getAllItems(); 25 | packs.push({ 26 | caption: path, 27 | canDelete: true, 28 | packageManager: packageManager, 29 | path: path, 30 | isExistDevDependencies: $.grep(ConstantHelpers_1.PS_Packagest, function (val, i) { 31 | return val.packageManager === packageManager; 32 | })[0].isExistDevDependencies 33 | }); 34 | localStorage.setItem(ConstantHelpers_1.LSKey_Package_Explorer_Packages, JSON.stringify(packs)); 35 | }; 36 | PackageExplorerHelpers.prototype.remove = function (path) { 37 | var packs = this.getAllItems(); 38 | var result = $.grep(packs, function (key, i) { 39 | return key.path !== path; 40 | }); 41 | localStorage.setItem(ConstantHelpers_1.LSKey_Package_Explorer_Packages, JSON.stringify(result)); 42 | }; 43 | PackageExplorerHelpers.prototype.removeAllList = function (packageManager) { 44 | var packs = this.getAllItems(); 45 | var result = $.grep(packs, function (key, i) { 46 | return key.packageManager !== packageManager; 47 | }); 48 | localStorage.setItem(ConstantHelpers_1.LSKey_Package_Explorer_Packages, JSON.stringify(result)); 49 | }; 50 | PackageExplorerHelpers.prototype.isExist = function (path) { 51 | var packs = this.getAllItems(); 52 | return $.grep(packs, function (key, i) { 53 | return key.path === path; 54 | }).length > 0; 55 | }; 56 | PackageExplorerHelpers.prototype.getAllItems = function () { 57 | var packs = localStorage.getItem(ConstantHelpers_1.LSKey_Package_Explorer_Packages); 58 | return packs === null ? [] : JSON.parse(packs); 59 | }; 60 | return PackageExplorerHelpers; 61 | }()); 62 | exports.PackageExplorerHelpers = PackageExplorerHelpers; 63 | -------------------------------------------------------------------------------- /templates/package-list-item.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 | dev 6 | 7 |
8 |
9 |
10 | 11 | 15 | 19 |
20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 |
-------------------------------------------------------------------------------- /js/directives/PackageListDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var MessageDialogHelpers_1 = require("../helpers/MessageDialogHelpers"); 4 | var PackageExplorerHelpers_1 = require("../helpers/PackageExplorerHelpers"); 5 | var fs = require('fs'); 6 | var remote = require('electron').remote; 7 | var shell = remote.shell; 8 | var PackageListDirective = (function () { 9 | function PackageListDirective() { 10 | this.restrict = 'E'; 11 | this.templateUrl = './templates/package-list.html'; 12 | this.transclude = true; 13 | } 14 | PackageListDirective.prototype.link = function (scope, element, attrs) { 15 | scope.$root.$watch('activePackageExplorerItem', function (newVal, oldVal) { 16 | if (newVal !== undefined) { 17 | scope.$root.showLoader = true; 18 | if (newVal.path !== undefined && newVal.path !== null) { 19 | fs.access(newVal.path, function (err) { 20 | if (err) { 21 | new MessageDialogHelpers_1.MessageDialogHelpers().confirm('The file does not exist!
Do you want to remove item from list?', function () { 22 | var activeItem = scope.$root.activeActivityBarMenuItem; 23 | new PackageExplorerHelpers_1.PackageExplorerHelpers().remove(newVal.path); 24 | scope.$apply(function () { 25 | scope.$root.packagePathList[activeItem.packageManager] = new PackageExplorerHelpers_1.PackageExplorerHelpers().getListItem(activeItem.packageManager); 26 | scope.$root.showLoader = false; 27 | }); 28 | }); 29 | } 30 | else { 31 | scope.$root.hidePackageOverlay = false; 32 | scope.$root.hidePackageDetailOverlay = false; 33 | scope.$root.searchVal = ''; 34 | scope.$root.reloadPackageList(); 35 | if (!scope.$$phase) 36 | scope.$apply(); 37 | } 38 | }); 39 | } 40 | else { 41 | scope.$root.hidePackageOverlay = false; 42 | scope.$root.hidePackageDetailOverlay = false; 43 | scope.$root.searchVal = ''; 44 | scope.$root.reloadPackageList(); 45 | if (!scope.$$phase) 46 | scope.$apply(); 47 | } 48 | } 49 | ; 50 | }); 51 | }; 52 | return PackageListDirective; 53 | }()); 54 | exports.PackageListDirective = PackageListDirective; 55 | -------------------------------------------------------------------------------- /src/scss/_package-explorer.scss: -------------------------------------------------------------------------------- 1 | @import '_mixins'; 2 | 3 | .package-explorer-container { 4 | height: 100%; 5 | 6 | .header { 7 | font-size: 13px; 8 | height: 36px; 9 | line-height: 36px; 10 | padding-left: 10px; 11 | padding-right: 10px; 12 | position: relative; 13 | // @include three-dots-overflow(); 14 | } 15 | 16 | .empty-list { 17 | font-size: 13px; 18 | text-align: center; 19 | margin-top: 12px; 20 | } 21 | 22 | package-explorer-list { 23 | position: relative; 24 | 25 | > ul { 26 | &.package-list { 27 | margin: 0; 28 | padding: 0; 29 | list-style: none; 30 | 31 | > li { 32 | position: relative; 33 | 34 | > a { 35 | display: block; 36 | padding: 10px; 37 | font-size: 12px; 38 | text-decoration: none; 39 | word-break: break-all; 40 | } 41 | 42 | &:hover { 43 | .context-menu-holder { 44 | display: block; 45 | } 46 | } 47 | } 48 | } 49 | } 50 | 51 | .context-menu-holder { 52 | display: none; 53 | position: absolute; 54 | top: 0; 55 | right: 0; 56 | bottom: 0; 57 | height: 100%; 58 | background-color: #2f333d; 59 | 60 | .list-holder { 61 | position: relative; 62 | top: 50%; 63 | transform: translateY(-50%); 64 | padding-right: 12px; 65 | padding-left: 10px; 66 | 67 | > ul { 68 | margin: 0; 69 | padding: 0; 70 | 71 | > li { 72 | list-style: none; 73 | display: inline-block; 74 | 75 | > a { 76 | font-size: 14px; 77 | padding: 0 3px; 78 | } 79 | } 80 | } 81 | } 82 | } 83 | } 84 | 85 | ul { 86 | &.package-list { 87 | margin: 0; 88 | padding: 0; 89 | list-style: none; 90 | 91 | li { 92 | div { 93 | &.package-list-item { 94 | display: block; 95 | padding: 10px; 96 | font-size: 12px; 97 | text-decoration: none; 98 | word-break: break-all; 99 | } 100 | } 101 | } 102 | } 103 | } 104 | 105 | .btn-icon { 106 | background: transparent; 107 | border: none; 108 | font-size: 14px; 109 | padding: 0 5px; 110 | margin-right: -5px; 111 | position: relative; 112 | top: -1px; 113 | } 114 | } -------------------------------------------------------------------------------- /images/activity-bar-icons/npm.svg: -------------------------------------------------------------------------------- 1 | Microsoft.VisualStudio.Services.Icons.Default -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NodeJs Package Manager 2 | ---------- 3 | 4 | 5 | **NodeJs Package Manager is an organizer for your npm and Bower packages.** So we can call **npm package manager** and **bower package manager** 6 | It's really easy to check, upgrade or downgrade packages, originally specified during in the one click. 7 | You can access all **README.md** files, **Contributors**, **Dependencies** and **DevDependencies** of package based on their versions. 8 | 9 |
10 | 11 | Screenshot 12 | ---------- 13 | ![NodeJs Package Manager](https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/master/images/documentation/readme-main.gif) 14 | 15 | You can 16 | ---------- 17 | 18 | - [See all**Global Packages** installed on your computer](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Global-Packages) 19 | - [Import **npm(packages.json)** & **Bower(bower.json)** files and see packages inside of them](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Open-Packages) 20 | - [Search **npm and Bower** packages](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Search-Mechanism) 21 | - [**Create (Init)** new **npm or Bower json** file with an easy-to-fill form](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Init-npm&bower-Json-File) 22 | - [Access **README** files, **Contributors**, **Dependencies** and **DevDependencies** of package based on their version](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Get-Package-Detail-According-To-Version) 23 | - [Check if **any updates exist** for installed packages](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Updates-of-Packages) 24 | - [**Install** a new package](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Installation) 25 | - [**Uninstall** an already installed package](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Uninstall-The-Package) 26 | - [**Update** to last or specified version](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Updates-of-Packages) 27 | - [**Downgrade** to specified version](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Downgrade-Package-Version) 28 | 29 | 30 | Installation 31 | ---------- 32 | **Executable Files** 33 | 34 | You can access all versions from [this link](https://github.com/gurayyarar/NodeJsPackageManager/releases) 35 | 36 | **Note** 37 | 38 | For now, this is only available on Windows Operation System. 39 | 40 | *Linux and MacOS versions coming soon!* 41 | 42 | 43 | **GitHub - For Developers** 44 | 45 | [Please follow these instructions](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Installation---For-Developers) 46 | 47 | 48 | Documentation 49 | ---------- 50 | You can visit the [WIKI page.](https://github.com/gurayyarar/NodeJsPackageManager/wiki) 51 | 52 | Theme Options 53 | ---------- 54 | |Dark Theme|Light Theme| 55 | |---|---| 56 | |![Dark Theme](https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/master/images/themes/dark-theme-big.jpg)|![Light Theme](https://raw.githubusercontent.com/gurayyarar/NodeJsPackageManager/master/images/themes/light-theme-big.jpg)| 57 | 58 | Change Logs 59 | ---------- 60 | You can check logs from [this link](https://github.com/gurayyarar/NodeJsPackageManager/wiki/Changelogs) 61 | 62 | License 63 | ---------- 64 | **NodeJs Package Manager** is an open source project that is licensed under the [MIT license](http://opensource.org/licenses/MIT). 65 | 66 | Donations 67 | ---------- 68 | Donations are **greatly appreciated!** 69 | 70 | **[BUY ME A COFFEE](http://bit.ly/2yEjtx5)** 71 | -------------------------------------------------------------------------------- /src/js/directives/PackageInitDirective.ts: -------------------------------------------------------------------------------- 1 | import { MessageDialogHelpers } from '../helpers/MessageDialogHelpers'; 2 | import { PackageInitFileHelpers } from '../helpers/PackageInitFileHelpers'; 3 | import { PackageExplorerHelpers } from '../helpers/PackageExplorerHelpers'; 4 | const fs = require('fs'); 5 | const remote = require('electron').remote; 6 | const dialog = remote.dialog; 7 | 8 | export class PackageInitDirective { 9 | restrict: string; 10 | templateUrl: string; 11 | transclude: boolean; 12 | 13 | constructor() { 14 | this.restrict = 'E' 15 | this.templateUrl = './templates/packages-init.html' 16 | this.transclude = true 17 | } 18 | 19 | link(scope: any, element: any, attrs: any) { 20 | scope.$root.$watch('activeActivityBarMenuItem', (newVal: any, oldVal: any) => { 21 | if (newVal !== undefined) { 22 | const packageManager: string = newVal.packageManager; 23 | const packageFileName: string = newVal.file; 24 | 25 | scope.form = {}; 26 | scope.form[packageManager] = { 27 | private: 'false', 28 | name: '', 29 | version: '', 30 | description: '' 31 | }; 32 | 33 | scope.scriptCommandInputs = [{ 34 | script_key: '', 35 | script_value: '' 36 | }]; 37 | 38 | scope.addNewScriptCommandInputs = () => { 39 | scope.scriptCommandInputs.push({ 40 | script_key: '', 41 | script_value: '' 42 | }); 43 | } 44 | 45 | scope.removeScriptCommandInputs = (i: number) => { 46 | scope.scriptCommandInputs.splice(i, 1); 47 | } 48 | 49 | scope.initPackageFile = () => { 50 | dialog.showSaveDialog({ 51 | title: 'Please choose a destination', 52 | defaultPath: `~/${packageFileName}` 53 | }, (fileName: string) => { 54 | if (fileName === undefined) { 55 | return; 56 | } else if (fileName !== undefined && fileName.indexOf(packageFileName) === -1) { 57 | new MessageDialogHelpers().error(`Please give name of ${packageFileName} to file for saving!`, 7500); 58 | return; 59 | } 60 | 61 | fs.writeFile(fileName, new PackageInitFileHelpers(scope).getJsonContent(), (err: any) => { 62 | if (err) { 63 | new MessageDialogHelpers().error(`File couldn't save because of: ${err.message}`); 64 | return; 65 | } 66 | 67 | $('#packageInitModal').modal('hide'); 68 | if (!new PackageExplorerHelpers().isExist(fileName)) { 69 | new PackageExplorerHelpers().add(packageManager, fileName); 70 | scope.$apply(() => { 71 | scope.$root.packagePathList[packageManager] = new PackageExplorerHelpers().getListItem(packageManager); 72 | }); 73 | } 74 | new MessageDialogHelpers().success('The file created successfully!', 3200); 75 | }); 76 | }) 77 | } 78 | } 79 | }); 80 | } 81 | } -------------------------------------------------------------------------------- /js/directives/PackageInitDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var MessageDialogHelpers_1 = require("../helpers/MessageDialogHelpers"); 4 | var PackageInitFileHelpers_1 = require("../helpers/PackageInitFileHelpers"); 5 | var PackageExplorerHelpers_1 = require("../helpers/PackageExplorerHelpers"); 6 | var fs = require('fs'); 7 | var remote = require('electron').remote; 8 | var dialog = remote.dialog; 9 | var PackageInitDirective = (function () { 10 | function PackageInitDirective() { 11 | this.restrict = 'E'; 12 | this.templateUrl = './templates/packages-init.html'; 13 | this.transclude = true; 14 | } 15 | PackageInitDirective.prototype.link = function (scope, element, attrs) { 16 | scope.$root.$watch('activeActivityBarMenuItem', function (newVal, oldVal) { 17 | if (newVal !== undefined) { 18 | var packageManager_1 = newVal.packageManager; 19 | var packageFileName_1 = newVal.file; 20 | scope.form = {}; 21 | scope.form[packageManager_1] = { 22 | private: 'false', 23 | name: '', 24 | version: '', 25 | description: '' 26 | }; 27 | scope.scriptCommandInputs = [{ 28 | script_key: '', 29 | script_value: '' 30 | }]; 31 | scope.addNewScriptCommandInputs = function () { 32 | scope.scriptCommandInputs.push({ 33 | script_key: '', 34 | script_value: '' 35 | }); 36 | }; 37 | scope.removeScriptCommandInputs = function (i) { 38 | scope.scriptCommandInputs.splice(i, 1); 39 | }; 40 | scope.initPackageFile = function () { 41 | dialog.showSaveDialog({ 42 | title: 'Please choose a destination', 43 | defaultPath: "~/" + packageFileName_1 44 | }, function (fileName) { 45 | if (fileName === undefined) { 46 | return; 47 | } 48 | else if (fileName !== undefined && fileName.indexOf(packageFileName_1) === -1) { 49 | new MessageDialogHelpers_1.MessageDialogHelpers().error("Please give name of " + packageFileName_1 + " to file for saving!", 7500); 50 | return; 51 | } 52 | fs.writeFile(fileName, new PackageInitFileHelpers_1.PackageInitFileHelpers(scope).getJsonContent(), function (err) { 53 | if (err) { 54 | new MessageDialogHelpers_1.MessageDialogHelpers().error("File couldn't save because of: " + err.message); 55 | return; 56 | } 57 | $('#packageInitModal').modal('hide'); 58 | if (!new PackageExplorerHelpers_1.PackageExplorerHelpers().isExist(fileName)) { 59 | new PackageExplorerHelpers_1.PackageExplorerHelpers().add(packageManager_1, fileName); 60 | scope.$apply(function () { 61 | scope.$root.packagePathList[packageManager_1] = new PackageExplorerHelpers_1.PackageExplorerHelpers().getListItem(packageManager_1); 62 | }); 63 | } 64 | new MessageDialogHelpers_1.MessageDialogHelpers().success('The file created successfully!', 3200); 65 | }); 66 | }); 67 | }; 68 | } 69 | }); 70 | }; 71 | return PackageInitDirective; 72 | }()); 73 | exports.PackageInitDirective = PackageInitDirective; 74 | -------------------------------------------------------------------------------- /templates/settings.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/scss/style.scss: -------------------------------------------------------------------------------- 1 | //@import '_theme-colors'; 2 | @import 'themes/_dark-theme'; 3 | @import 'themes/_light-theme'; 4 | @import '_package-explorer'; 5 | @import '_footer'; 6 | @import '_activity-bar'; 7 | @import '_mixins'; 8 | @import '_packages'; 9 | @import '_helpers'; 10 | @import '_key-frames'; 11 | @import '_message-dialog'; 12 | @import '_modal'; 13 | @import '_buttons'; 14 | @import '_navtabs'; 15 | @import '_settings'; 16 | 17 | html, 18 | body { 19 | height: 100%; 20 | min-height: 100%; 21 | font-family: 'Open Sans', Arial, Helvetica, sans-serif; 22 | margin: 0; 23 | padding: 0; 24 | user-select: none; 25 | cursor: default; 26 | } 27 | 28 | html, 29 | body, 30 | input, 31 | textarea, 32 | select, 33 | option, 34 | button { 35 | outline: none !important; 36 | 37 | &:hover, 38 | &:focus, 39 | &:active { 40 | outline: none !important; 41 | } 42 | } 43 | 44 | .animated { 45 | -webkit-animation-duration: .5s !important; 46 | animation-duration: .5s !important; 47 | } 48 | 49 | ::-webkit-scrollbar { 50 | width: 9px; 51 | z-index: 999999; 52 | } 53 | 54 | ::-webkit-scrollbar-track { 55 | border: none; 56 | } 57 | 58 | .package-detail-container { 59 | &:not(.setup-container), 60 | &:not(.nav-tabs) { 61 | user-select: auto !important; 62 | } 63 | } 64 | 65 | select:active, select:hover { 66 | option { 67 | outline-color: #000; 68 | } 69 | } 70 | 71 | .workbench-container { 72 | width: 100%; 73 | height: calc(100% - 24px); 74 | margin: 0; 75 | padding: 0; 76 | display: flex; 77 | 78 | activity-bar { 79 | width: 50px; 80 | height: 100%; 81 | } 82 | } 83 | 84 | .main-split-pane { 85 | &.fixed-left { 86 | > .split-pane-component { 87 | &:first-child { 88 | min-width: 240px; 89 | } 90 | 91 | &:last-child { 92 | min-width: 240px; 93 | } 94 | } 95 | 96 | .split-pane-divider { 97 | width: 8px; 98 | margin-left: -4px; 99 | cursor: e-resize; 100 | } 101 | } 102 | } 103 | 104 | .form-control { 105 | border-radius: 0; 106 | box-shadow: none; 107 | height: 32px; 108 | padding: 6px 7px 7px 10px; 109 | font-size: 13px; 110 | transition: none; 111 | 112 | &:active, 113 | &:hover, 114 | &:focus { 115 | box-shadow: none; 116 | } 117 | } 118 | 119 | .has-search-icon { 120 | position: relative; 121 | 122 | .form-control { 123 | padding-left: 28px; 124 | padding-right: 26px; 125 | } 126 | 127 | &:not(.input-loader) { 128 | &:after { 129 | font-family: 'FontAwesome'; 130 | content: "\f002"; 131 | position: absolute; 132 | top: 5px; 133 | left: 9px; 134 | } 135 | } 136 | 137 | &.input-loader { 138 | &:after { 139 | content: " "; 140 | border-radius: 50%; 141 | display: inline-block; 142 | position: absolute; 143 | top: 8px; 144 | left: 7px; 145 | width: 16px; 146 | height: 16px; 147 | animation: spin 1s infinite linear; 148 | border-width: 2px; 149 | border-style: solid; 150 | margin-left: auto; 151 | margin-right: auto; 152 | } 153 | } 154 | } 155 | 156 | .loading { 157 | border-radius: 50%; 158 | width: 20px; 159 | height: 20px; 160 | animation: spin 1s infinite linear; 161 | border-width: 2px; 162 | border-style: solid; 163 | margin-left: auto; 164 | margin-right: auto; 165 | } 166 | 167 | package-list-item { 168 | .controls { 169 | position: relative; 170 | 171 | .loading { 172 | position: absolute; 173 | top: 0; 174 | right: 0; 175 | width: 16px; 176 | height: 16px; 177 | } 178 | 179 | .btn-sm { 180 | padding: 1px 5px; 181 | font-size: 11px; 182 | } 183 | } 184 | } 185 | 186 | .dropdown-menu { 187 | .divider { 188 | margin: 3px 0; 189 | } 190 | } 191 | -------------------------------------------------------------------------------- /src/js/directives/PackageExplorerListDirective.ts: -------------------------------------------------------------------------------- 1 | import { PackageHelpers } from '../helpers/PackageHelpers'; 2 | import { IPackageExplorer } from '../interfaces/IPackageExplorer'; 3 | import { NpmService } from '../services/NpmService'; 4 | import { IPackagest } from "../interfaces/IPackagest"; 5 | import { MessageDialogHelpers } from '../helpers/MessageDialogHelpers'; 6 | import { PackageExplorerHelpers } from '../helpers/PackageExplorerHelpers'; 7 | const fs = require('fs'); 8 | const remote = require('electron').remote; 9 | const dialog = remote.dialog; 10 | const shell = remote.shell; 11 | 12 | export class PackageExplorerListDirective { 13 | restrict: string; 14 | templateUrl: string; 15 | transclude: boolean; 16 | scope: any; 17 | 18 | constructor() { 19 | this.restrict = 'E' 20 | this.templateUrl = './templates/package-explorer-list.html' 21 | this.transclude = true 22 | this.scope = { 23 | item: '=item' 24 | } 25 | } 26 | 27 | link(scope: any, element: any, attrs: any) { 28 | 29 | scope.selectPackageExplorerItem = (item: IPackageExplorer) => { 30 | scope.$root.activePackageExplorerItem = item; 31 | } 32 | 33 | scope.openFile = () => { 34 | const activeItem: IPackagest = scope.$root.activeActivityBarMenuItem; 35 | const packageManager: string = activeItem.packageManager; 36 | 37 | dialog.showOpenDialog({ filters: [{ name: packageManager, extensions: ['json'] }] }, (fileNames: string[]) => { 38 | if (fileNames === undefined) return; 39 | 40 | const file: string = fileNames[0]; 41 | if (file.indexOf(activeItem.file) === -1) { 42 | new MessageDialogHelpers().error(`Please select ${activeItem.file} file!`, 5000); 43 | return; 44 | } 45 | 46 | if (new PackageExplorerHelpers().isExist(file)) { 47 | new MessageDialogHelpers().error('You already opened this file. Please choose on list below!', 6000); 48 | return; 49 | } 50 | else { 51 | new PackageExplorerHelpers().add(packageManager, file); 52 | scope.$apply(() => { 53 | scope.$root.packagePathList[packageManager] = new PackageExplorerHelpers().getListItem(packageManager); 54 | }); 55 | } 56 | }); 57 | } 58 | 59 | scope.initFile = () => { 60 | $('#packageInitModal').modal('show'); 61 | } 62 | 63 | scope.clearList = () => { 64 | const activeItem: IPackagest = scope.$root.activeActivityBarMenuItem; 65 | 66 | new MessageDialogHelpers().confirm(`Are you sure want to delete list on ${activeItem.packageManager} package?`, () => { 67 | scope.$root.packageList = {}; 68 | new PackageExplorerHelpers().removeAllList(activeItem.packageManager); 69 | scope.$apply(() => { 70 | scope.$root.packagePathList[activeItem.packageManager] = new PackageExplorerHelpers().getListItem(activeItem.packageManager); 71 | }); 72 | }) 73 | } 74 | 75 | scope.revealInExplorer = (path: string) => { 76 | fs.access(path, (err: any) => { 77 | if (err) { 78 | new MessageDialogHelpers().confirm('The file does not exist!
Do you want to remove item from list?', () => { 79 | const activeItem: IPackagest = scope.$root.activeActivityBarMenuItem; 80 | new PackageExplorerHelpers().remove(path); 81 | scope.$apply(() => { 82 | scope.$root.packagePathList[activeItem.packageManager] = new PackageExplorerHelpers().getListItem(activeItem.packageManager); 83 | }); 84 | }); 85 | } else { 86 | shell.showItemInFolder(path); 87 | } 88 | }); 89 | } 90 | 91 | scope.removeFromList = (path: string) => { 92 | new MessageDialogHelpers().confirm('Are you sure want to remove from list?', () => { 93 | const activeItem: IPackagest = scope.$root.activeActivityBarMenuItem; 94 | new PackageExplorerHelpers().remove(path); 95 | scope.$apply(() => { 96 | scope.$root.packagePathList[activeItem.packageManager] = new PackageExplorerHelpers().getListItem(activeItem.packageManager); 97 | 98 | if (scope.$root.activePackageExplorerItem !== undefined && scope.$root.activePackageExplorerItem.path === path) { 99 | scope.$root.hidePackageOverlay = false; 100 | scope.$root.hidePackageDetailOverlay = false; 101 | scope.$root.searchVal = ''; 102 | } 103 | }); 104 | }); 105 | } 106 | } 107 | } -------------------------------------------------------------------------------- /js/directives/PackageExplorerListDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var MessageDialogHelpers_1 = require("../helpers/MessageDialogHelpers"); 4 | var PackageExplorerHelpers_1 = require("../helpers/PackageExplorerHelpers"); 5 | var fs = require('fs'); 6 | var remote = require('electron').remote; 7 | var dialog = remote.dialog; 8 | var shell = remote.shell; 9 | var PackageExplorerListDirective = (function () { 10 | function PackageExplorerListDirective() { 11 | this.restrict = 'E'; 12 | this.templateUrl = './templates/package-explorer-list.html'; 13 | this.transclude = true; 14 | this.scope = { 15 | item: '=item' 16 | }; 17 | } 18 | PackageExplorerListDirective.prototype.link = function (scope, element, attrs) { 19 | scope.selectPackageExplorerItem = function (item) { 20 | scope.$root.activePackageExplorerItem = item; 21 | }; 22 | scope.openFile = function () { 23 | var activeItem = scope.$root.activeActivityBarMenuItem; 24 | var packageManager = activeItem.packageManager; 25 | dialog.showOpenDialog({ filters: [{ name: packageManager, extensions: ['json'] }] }, function (fileNames) { 26 | if (fileNames === undefined) 27 | return; 28 | var file = fileNames[0]; 29 | if (file.indexOf(activeItem.file) === -1) { 30 | new MessageDialogHelpers_1.MessageDialogHelpers().error("Please select " + activeItem.file + " file!", 5000); 31 | return; 32 | } 33 | if (new PackageExplorerHelpers_1.PackageExplorerHelpers().isExist(file)) { 34 | new MessageDialogHelpers_1.MessageDialogHelpers().error('You already opened this file. Please choose on list below!', 6000); 35 | return; 36 | } 37 | else { 38 | new PackageExplorerHelpers_1.PackageExplorerHelpers().add(packageManager, file); 39 | scope.$apply(function () { 40 | scope.$root.packagePathList[packageManager] = new PackageExplorerHelpers_1.PackageExplorerHelpers().getListItem(packageManager); 41 | }); 42 | } 43 | }); 44 | }; 45 | scope.initFile = function () { 46 | $('#packageInitModal').modal('show'); 47 | }; 48 | scope.clearList = function () { 49 | var activeItem = scope.$root.activeActivityBarMenuItem; 50 | new MessageDialogHelpers_1.MessageDialogHelpers().confirm("Are you sure want to delete list on " + activeItem.packageManager + " package?", function () { 51 | scope.$root.packageList = {}; 52 | new PackageExplorerHelpers_1.PackageExplorerHelpers().removeAllList(activeItem.packageManager); 53 | scope.$apply(function () { 54 | scope.$root.packagePathList[activeItem.packageManager] = new PackageExplorerHelpers_1.PackageExplorerHelpers().getListItem(activeItem.packageManager); 55 | }); 56 | }); 57 | }; 58 | scope.revealInExplorer = function (path) { 59 | fs.access(path, function (err) { 60 | if (err) { 61 | new MessageDialogHelpers_1.MessageDialogHelpers().confirm('The file does not exist!
Do you want to remove item from list?', function () { 62 | var activeItem = scope.$root.activeActivityBarMenuItem; 63 | new PackageExplorerHelpers_1.PackageExplorerHelpers().remove(path); 64 | scope.$apply(function () { 65 | scope.$root.packagePathList[activeItem.packageManager] = new PackageExplorerHelpers_1.PackageExplorerHelpers().getListItem(activeItem.packageManager); 66 | }); 67 | }); 68 | } 69 | else { 70 | shell.showItemInFolder(path); 71 | } 72 | }); 73 | }; 74 | scope.removeFromList = function (path) { 75 | new MessageDialogHelpers_1.MessageDialogHelpers().confirm('Are you sure want to remove from list?', function () { 76 | var activeItem = scope.$root.activeActivityBarMenuItem; 77 | new PackageExplorerHelpers_1.PackageExplorerHelpers().remove(path); 78 | scope.$apply(function () { 79 | scope.$root.packagePathList[activeItem.packageManager] = new PackageExplorerHelpers_1.PackageExplorerHelpers().getListItem(activeItem.packageManager); 80 | if (scope.$root.activePackageExplorerItem !== undefined && scope.$root.activePackageExplorerItem.path === path) { 81 | scope.$root.hidePackageOverlay = false; 82 | scope.$root.hidePackageDetailOverlay = false; 83 | scope.$root.searchVal = ''; 84 | } 85 | }); 86 | }); 87 | }; 88 | }; 89 | return PackageExplorerListDirective; 90 | }()); 91 | exports.PackageExplorerListDirective = PackageExplorerListDirective; 92 | -------------------------------------------------------------------------------- /src/js/helpers/PackageInitFileHelpers.ts: -------------------------------------------------------------------------------- 1 | export class PackageInitFileHelpers { 2 | scope: any; 3 | 4 | constructor(scope: any) { 5 | this.scope = scope; 6 | } 7 | 8 | getJsonContent() { 9 | const packageManager: string = this.scope.$root.activeActivityBarMenuItem.packageManager; 10 | 11 | if (packageManager === 'npm') { 12 | return this.packageNpm(); 13 | } else if (packageManager === 'bower') { 14 | return this.packageBower(); 15 | } 16 | } 17 | 18 | private packageNpm(): string { 19 | var formValues: any = this.scope.form['npm']; 20 | var scriptCommandInputs: any = this.scope.scriptCommandInputs; 21 | let author: string = `${formValues.author_name} <${formValues.author_email}> (${formValues.author_url})`; 22 | author = author.replace(/undefined/g, '').replace(' <>', '').replace(' ()', ''); 23 | 24 | const result: any = { 25 | name: formValues.name, 26 | version: formValues.version, 27 | description: formValues.description 28 | } 29 | 30 | if (formValues.main !== undefined && formValues.main !== '') { 31 | result['main'] = formValues.main; 32 | } 33 | 34 | if (scriptCommandInputs.length > 0) { 35 | result.scripts = {}; 36 | 37 | scriptCommandInputs.forEach((value: any, i: number) => { 38 | result.scripts[value.script_key] = value.script_value; 39 | }); 40 | } 41 | 42 | if (formValues.repository_type !== undefined && formValues.repository_type !== '' && formValues.repository_url !== undefined && formValues.repository_url !== '') { 43 | result.repository = {}; 44 | result.repository['type'] = formValues.repository_type; 45 | result.repository['url'] = formValues.repository_url; 46 | } 47 | 48 | if (formValues.keywords !== undefined && formValues.keywords !== '') { 49 | result.keywords = []; 50 | 51 | if (formValues.keywords.indexOf(',') === -1) { 52 | result.keywords.push(formValues.keywords.trim()); 53 | } else { 54 | formValues.keywords.split(',').forEach((value: any, i: number) => { 55 | result.keywords.push(value.trim()); 56 | }); 57 | } 58 | } 59 | 60 | if (author !== undefined && author !== '') { 61 | result.author = author; 62 | } 63 | 64 | if (formValues.license !== undefined && formValues.license !== '') { 65 | result.license = formValues.license; 66 | } 67 | 68 | result.private = formValues.private === 'true'; 69 | 70 | if (formValues.bugs_url !== undefined && formValues.bugs_url !== '') { 71 | result.bugs = {}; 72 | result.bugs['url'] = formValues.bugs_url; 73 | } 74 | 75 | if (formValues.homepage !== undefined && formValues.homepage !== '') { 76 | result.homepage = formValues.homepage; 77 | } 78 | 79 | return JSON.stringify(result, null, 2); 80 | } 81 | 82 | private packageBower() { 83 | var formValues: any = this.scope.form['bower']; 84 | 85 | const result: any = { 86 | name: formValues.name, 87 | version: formValues.version, 88 | description: formValues.description 89 | } 90 | 91 | if (formValues.main !== undefined && formValues.main !== '') { 92 | result['main'] = formValues.main; 93 | } 94 | 95 | if (formValues.authors !== undefined && formValues.authors !== '') { 96 | result.authors = []; 97 | 98 | if (formValues.authors.indexOf(',') === -1) { 99 | result.authors.push(formValues.authors.trim()); 100 | } else { 101 | formValues.authors.split(',').forEach((value: any, i: number) => { 102 | result.authors.push(value.trim()); 103 | }); 104 | } 105 | } 106 | 107 | if (formValues.keywords !== undefined && formValues.keywords !== '') { 108 | result.keywords = []; 109 | 110 | if (formValues.keywords.indexOf(',') === -1) { 111 | result.keywords.push(formValues.keywords.trim()); 112 | } else { 113 | formValues.keywords.split(',').forEach((value: any, i: number) => { 114 | result.keywords.push(value.trim()); 115 | }); 116 | } 117 | } 118 | 119 | if (formValues.license !== undefined && formValues.license !== '') { 120 | result.license = formValues.license; 121 | } 122 | 123 | result.private = formValues.private === 'true'; 124 | 125 | if (formValues.homepage !== undefined && formValues.homepage !== '') { 126 | result.homepage = formValues.homepage; 127 | } 128 | 129 | if (formValues.ignore !== undefined && formValues.ignore !== '') { 130 | result.ignore = []; 131 | 132 | if (formValues.ignore.indexOf(',') === -1) { 133 | result.ignore.push(formValues.ignore.trim()); 134 | } else { 135 | formValues.ignore.split(',').forEach((value: any, i: number) => { 136 | result.ignore.push(value.trim()); 137 | }); 138 | } 139 | } 140 | 141 | return JSON.stringify(result, null, 2); 142 | } 143 | } -------------------------------------------------------------------------------- /js/helpers/PackageInitFileHelpers.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var PackageInitFileHelpers = (function () { 4 | function PackageInitFileHelpers(scope) { 5 | this.scope = scope; 6 | } 7 | PackageInitFileHelpers.prototype.getJsonContent = function () { 8 | var packageManager = this.scope.$root.activeActivityBarMenuItem.packageManager; 9 | if (packageManager === 'npm') { 10 | return this.packageNpm(); 11 | } 12 | else if (packageManager === 'bower') { 13 | return this.packageBower(); 14 | } 15 | }; 16 | PackageInitFileHelpers.prototype.packageNpm = function () { 17 | var formValues = this.scope.form['npm']; 18 | var scriptCommandInputs = this.scope.scriptCommandInputs; 19 | var author = formValues.author_name + " <" + formValues.author_email + "> (" + formValues.author_url + ")"; 20 | author = author.replace(/undefined/g, '').replace(' <>', '').replace(' ()', ''); 21 | var result = { 22 | name: formValues.name, 23 | version: formValues.version, 24 | description: formValues.description 25 | }; 26 | if (formValues.main !== undefined && formValues.main !== '') { 27 | result['main'] = formValues.main; 28 | } 29 | if (scriptCommandInputs.length > 0) { 30 | result.scripts = {}; 31 | scriptCommandInputs.forEach(function (value, i) { 32 | result.scripts[value.script_key] = value.script_value; 33 | }); 34 | } 35 | if (formValues.repository_type !== undefined && formValues.repository_type !== '' && formValues.repository_url !== undefined && formValues.repository_url !== '') { 36 | result.repository = {}; 37 | result.repository['type'] = formValues.repository_type; 38 | result.repository['url'] = formValues.repository_url; 39 | } 40 | if (formValues.keywords !== undefined && formValues.keywords !== '') { 41 | result.keywords = []; 42 | if (formValues.keywords.indexOf(',') === -1) { 43 | result.keywords.push(formValues.keywords.trim()); 44 | } 45 | else { 46 | formValues.keywords.split(',').forEach(function (value, i) { 47 | result.keywords.push(value.trim()); 48 | }); 49 | } 50 | } 51 | if (author !== undefined && author !== '') { 52 | result.author = author; 53 | } 54 | if (formValues.license !== undefined && formValues.license !== '') { 55 | result.license = formValues.license; 56 | } 57 | result.private = formValues.private === 'true'; 58 | if (formValues.bugs_url !== undefined && formValues.bugs_url !== '') { 59 | result.bugs = {}; 60 | result.bugs['url'] = formValues.bugs_url; 61 | } 62 | if (formValues.homepage !== undefined && formValues.homepage !== '') { 63 | result.homepage = formValues.homepage; 64 | } 65 | return JSON.stringify(result, null, 2); 66 | }; 67 | PackageInitFileHelpers.prototype.packageBower = function () { 68 | var formValues = this.scope.form['bower']; 69 | var result = { 70 | name: formValues.name, 71 | version: formValues.version, 72 | description: formValues.description 73 | }; 74 | if (formValues.main !== undefined && formValues.main !== '') { 75 | result['main'] = formValues.main; 76 | } 77 | if (formValues.authors !== undefined && formValues.authors !== '') { 78 | result.authors = []; 79 | if (formValues.authors.indexOf(',') === -1) { 80 | result.authors.push(formValues.authors.trim()); 81 | } 82 | else { 83 | formValues.authors.split(',').forEach(function (value, i) { 84 | result.authors.push(value.trim()); 85 | }); 86 | } 87 | } 88 | if (formValues.keywords !== undefined && formValues.keywords !== '') { 89 | result.keywords = []; 90 | if (formValues.keywords.indexOf(',') === -1) { 91 | result.keywords.push(formValues.keywords.trim()); 92 | } 93 | else { 94 | formValues.keywords.split(',').forEach(function (value, i) { 95 | result.keywords.push(value.trim()); 96 | }); 97 | } 98 | } 99 | if (formValues.license !== undefined && formValues.license !== '') { 100 | result.license = formValues.license; 101 | } 102 | result.private = formValues.private === 'true'; 103 | if (formValues.homepage !== undefined && formValues.homepage !== '') { 104 | result.homepage = formValues.homepage; 105 | } 106 | if (formValues.ignore !== undefined && formValues.ignore !== '') { 107 | result.ignore = []; 108 | if (formValues.ignore.indexOf(',') === -1) { 109 | result.ignore.push(formValues.ignore.trim()); 110 | } 111 | else { 112 | formValues.ignore.split(',').forEach(function (value, i) { 113 | result.ignore.push(value.trim()); 114 | }); 115 | } 116 | } 117 | return JSON.stringify(result, null, 2); 118 | }; 119 | return PackageInitFileHelpers; 120 | }()); 121 | exports.PackageInitFileHelpers = PackageInitFileHelpers; 122 | -------------------------------------------------------------------------------- /src/js/directives/PackageDirective.ts: -------------------------------------------------------------------------------- 1 | import { PackageHelpers } from '../helpers/PackageHelpers'; 2 | import { IPackageExplorer } from '../interfaces/IPackageExplorer'; 3 | export class PackageDirective { 4 | restrict: string; 5 | templateUrl: string; 6 | transclude: boolean; 7 | 8 | constructor() { 9 | this.restrict = 'E' 10 | this.templateUrl = './templates/packages.html' 11 | this.transclude = true 12 | } 13 | 14 | link(scope: any, element: any, attrs: any) { 15 | scope.makeFilter = (command: string) => { 16 | scope.$root.searchVal = `${command} `; 17 | $('.js-package-search').focus(); 18 | } 19 | 20 | scope.clearSearch = () => { 21 | scope.$root.searchVal = ''; 22 | $('.js-package-search').focus(); 23 | } 24 | 25 | scope.$root.getFilteredData = () => { 26 | let queryVal: string = scope.$root.searchVal; 27 | 28 | if (queryVal === '' || queryVal === null) { 29 | scope.$root.packageList = new PackageHelpers(scope).getAllInstalledPackages(); 30 | } 31 | else if (queryVal.indexOf('@installed') > -1) { 32 | const query = queryVal.replace('@installed', '').trim(); 33 | let installedPackages = new PackageHelpers(scope).getAllInstalledPackages(); 34 | 35 | if (query !== '') { 36 | installedPackages = $.grep(installedPackages, (key, i) => { 37 | return key.name.indexOf(query) > -1; 38 | }); 39 | } 40 | 41 | scope.$root.packageList = installedPackages; 42 | } 43 | else if (queryVal.indexOf('@update') > -1) { 44 | const query = queryVal.replace('@update', '').trim(); 45 | let installedPackages = new PackageHelpers(scope).getAllInstalledPackages(); 46 | 47 | let updateAvailablePackages = $.grep(installedPackages, (key, i) => { 48 | return scope.$root.packages[key.name].listItemControl.update === true; 49 | }); 50 | 51 | if (query !== '') { 52 | updateAvailablePackages = $.grep(updateAvailablePackages, (key, i) => { 53 | return key.name.indexOf(query) > -1; 54 | }); 55 | } 56 | 57 | scope.$root.packageList = updateAvailablePackages; 58 | } 59 | else if (queryVal.indexOf('@devdependencies') > -1) { 60 | const query = queryVal.replace('@devdependencies', '').trim(); 61 | let installedPackages = new PackageHelpers(scope).getAllInstalledPackages(); 62 | 63 | let packs = $.grep(installedPackages, (key, i) => { 64 | return scope.$root.packages[key.name].isDevDependencies === true; 65 | }); 66 | 67 | if (query !== '') { 68 | packs = $.grep(packs, (key, i) => { 69 | return key.name.indexOf(query) > -1; 70 | }); 71 | } 72 | 73 | scope.$root.packageList = packs; 74 | } 75 | else if (queryVal.indexOf('@dependencies') > -1) { 76 | const query = queryVal.replace('@dependencies', '').trim(); 77 | let installedPackages = new PackageHelpers(scope).getAllInstalledPackages(); 78 | 79 | let packs = $.grep(installedPackages, (key, i) => { 80 | return scope.$root.packages[key.name].isDevDependencies === false; 81 | }); 82 | 83 | if (query !== '') { 84 | packs = $.grep(packs, (key, i) => { 85 | return key.name.indexOf(query) > -1; 86 | }); 87 | } 88 | 89 | scope.$root.packageList = packs; 90 | } 91 | else { 92 | scope.$root.showInputLoader = true; 93 | new PackageHelpers(scope).getSearchResult(queryVal, (result: any) => { 94 | scope.$root.$apply(() => { 95 | scope.$root.packageList = result; 96 | scope.$root.showInputLoader = false; 97 | }); 98 | }) 99 | } 100 | } 101 | 102 | scope.$root.$watch('searchVal', (newVal: string, oldVal: string) => { 103 | if (newVal !== undefined) scope.$root.getFilteredData(); 104 | }); 105 | 106 | scope.$root.reloadPackageList = () => { 107 | const activeItem: IPackageExplorer = scope.$root.activePackageExplorerItem; 108 | 109 | scope.$root.hidePackageDetailOverlay = false; 110 | scope.$root.packageList = {}; 111 | scope.$root.showLoader = true; 112 | scope.$root.searchVal = ''; 113 | new PackageHelpers(scope).resetPackages(); 114 | new PackageHelpers(scope).getInstalledPackagesFromFile(activeItem.packageManager, activeItem.path, (result: any) => { 115 | scope.$root.$apply(() => { 116 | scope.$root.hidePackageOverlay = true; 117 | 118 | if (result.length === 0) { 119 | scope.$root.showLoader = false; 120 | } else { 121 | scope.$root.loadedPackageLength = result.length; 122 | } 123 | 124 | scope.$root.packageList = result; 125 | }); 126 | }); 127 | } 128 | } 129 | } -------------------------------------------------------------------------------- /src/js/services/NpmService.ts: -------------------------------------------------------------------------------- 1 | import { IPackage } from '../interfaces/IPackage'; 2 | import { IPackageCommand } from '../interfaces/IPackageCommand'; 3 | import { MessageDialogHelpers } from '../helpers/MessageDialogHelpers'; 4 | const childProcess = require('child_process'); 5 | 6 | export class NpmService { 7 | getGlobalPackages(callback: any) { 8 | childProcess.exec('npm ls -g --depth=0 --json', { maxBuffer: 1024 * 500 }, (error: any, stdout: any, stderr: any) => { 9 | let result: IPackage[] = []; 10 | let response: any = JSON.parse(stdout).dependencies; 11 | 12 | $.each(response, function (key, value) { 13 | result.push({ 14 | name: key, 15 | version: value.version 16 | }); 17 | }); 18 | 19 | setTimeout(callback(result), 250); 20 | }); 21 | } 22 | 23 | getInstalledPackagesFromFile(filePath: string, callback: any) { 24 | filePath = filePath.replace('\\package.json', ''); 25 | childProcess.exec(`npm ls --depth=0 --json`, { cwd: filePath, maxBuffer: 1024 * 500 }, (error: any, stdout: any, stderr: any) => { 26 | callback(JSON.parse(stdout)); 27 | }); 28 | } 29 | 30 | getPackageDetailInfo(packageName: string, callback: any) { 31 | childProcess.exec(`npm info ${packageName} --json`, { maxBuffer: 1024 * 500 }, (error: any, stdout: any, stderr: any) => { 32 | callback(JSON.parse(stdout)); 33 | }); 34 | } 35 | 36 | getPackageDetailInfoByVersion(packageName: string, version: string, callback: any) { 37 | childProcess.exec(`npm info ${packageName}@${version} --json`, { maxBuffer: 1024 * 500 }, (error: any, stdout: any, stderr: any) => { 38 | const parsedData: any = JSON.parse(stdout); 39 | 40 | const userReposStr: string = parsedData.repository.url.replace('git+https://github.com/', '').replace('.git', '').replace('https://github.com/', ''); 41 | let readMeUrl: string = `https://raw.githubusercontent.com/${userReposStr}/`; 42 | 43 | $.ajax({ 44 | url: `${readMeUrl}v${parsedData.version}/README.md`, 45 | type: 'GET', 46 | data: {}, 47 | complete: (xhr: any, statusText: any) => { 48 | if (xhr.status === 404) { 49 | $.ajax({ 50 | url: `${readMeUrl}${parsedData.version}/README.md`, 51 | type: 'GET', 52 | data: {}, 53 | complete: (subXhr: any, subStatusText: any) => { 54 | callback(parsedData, subXhr.status !== 404 ? subXhr.responseText : undefined); 55 | } 56 | }) 57 | } else { 58 | callback(parsedData, xhr.responseText); 59 | } 60 | } 61 | }); 62 | }); 63 | } 64 | 65 | getLatestVersion(packageName: string, callback: any) { 66 | childProcess.exec(`npm view ${packageName} version --json`, (error: any, stdout: any, stderr: any) => { 67 | callback(JSON.parse(stdout)); 68 | }); 69 | } 70 | 71 | getSearchResult(query: string, callback: any) { 72 | childProcess.exec(`npm search ${query} --no-description --json`, (error: any, stdout: any, stderr: any) => { 73 | callback(JSON.parse(stdout)); 74 | }); 75 | } 76 | 77 | install(packages: IPackageCommand, callback: any) { 78 | let installOptions: any = { 79 | maxBuffer: 1024 * 500 80 | }; 81 | 82 | let command: string = `npm install ${packages.packages.join(' ')}`; 83 | 84 | if (packages.isGlobal) { 85 | command += ' -g'; 86 | } else { 87 | command += ' --save'; 88 | if (packages.isDevDependency) command += '-dev'; 89 | installOptions['cwd'] = packages.packagePath.replace('\\package.json', ''); 90 | } 91 | 92 | command += ' --force --json'; 93 | 94 | childProcess.exec(command, installOptions, (err: any, stdout: any, stderr: any) => { 95 | if (err) { 96 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 97 | return; 98 | } 99 | callback(); 100 | }); 101 | } 102 | 103 | uninstall(packages: IPackageCommand, callback: any) { 104 | let uninstallOptions: any = { 105 | maxBuffer: 1024 * 500 106 | }; 107 | 108 | let command: string = `npm uninstall ${packages.packages.join(' ')}`; 109 | 110 | if (packages.isGlobal) { 111 | command += ' -g'; 112 | } else { 113 | command += ' --save'; 114 | if (packages.isDevDependency) command += '-dev'; 115 | uninstallOptions['cwd'] = packages.packagePath.replace('\\package.json', ''); 116 | } 117 | 118 | command += ' --force --json'; 119 | 120 | childProcess.exec(command, uninstallOptions, (err: any, stdout: any, stderr: any) => { 121 | if (err) { 122 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 123 | callback(); 124 | } 125 | callback(); 126 | }); 127 | } 128 | 129 | update(packages: IPackageCommand, callback: any) { 130 | this.install(packages, callback); 131 | } 132 | 133 | downgrade(packages: IPackageCommand, callback: any) { 134 | this.install(packages, callback); 135 | } 136 | } -------------------------------------------------------------------------------- /src/js/services/BowerService.ts: -------------------------------------------------------------------------------- 1 | import { IPackage } from '../interfaces/IPackage'; 2 | import { MessageDialogHelpers } from '../helpers/MessageDialogHelpers'; 3 | import { IPackageCommand } from '../interfaces/IPackageCommand'; 4 | import { IPackageExplorer } from '../interfaces/IPackageExplorer'; 5 | const childProcess = require('child_process'); 6 | const bower = require('bower'); 7 | const fs = require('fs'); 8 | 9 | export class BowerService { 10 | getInstalledPackagesFromFile(filePath: string, callback: any) { 11 | filePath = filePath.replace('\\bower.json', ''); 12 | bower.commands.list({}, { 'cwd': filePath, 'offline': true }) 13 | .on('end', callback) 14 | .on('error', (err: any) => { 15 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 16 | callback(); 17 | }); 18 | } 19 | 20 | getPackageDetailInfo(packageName: string, callback: any) { 21 | bower.commands.info(packageName, undefined, {}) 22 | .on('end', callback) 23 | .on('error', (err: any) => { 24 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 25 | callback(); 26 | }); 27 | } 28 | 29 | getPackageDetailByVersion(packageName: string, version: string, callback: any) { 30 | bower.commands.info(`${packageName}#${version}`, undefined, {}) 31 | .on('log', (log: any) => { 32 | if (log.level === 'info') { 33 | const userReposStr: string = log.data.resolver.source.replace('https://github.com/', '').replace('.git', ''); 34 | let readMeUrl: string = `https://raw.githubusercontent.com/${userReposStr}/`; 35 | 36 | if (log.data.pkgMeta !== undefined && log.data.pkgMeta._resolution !== undefined) { 37 | $.ajax({ 38 | url: `${readMeUrl}${log.data.pkgMeta._resolution.tag}/README.md`, 39 | type: 'GET', 40 | data: {}, 41 | complete: function (xhr, statusText) { 42 | callback(log, xhr.status !== 404 ? xhr.responseText : undefined); 43 | } 44 | }); 45 | } else { 46 | $.ajax({ 47 | url: `${readMeUrl}v${log.data.endpoint.target}/README.md`, 48 | type: 'GET', 49 | data: {}, 50 | complete: (xhr: any, statusText: any) => { 51 | if (xhr.status === 404) { 52 | $.ajax({ 53 | url: `${readMeUrl}${log.data.endpoint.target}/README.md`, 54 | type: 'GET', 55 | data: {}, 56 | complete: (subXhr: any, subStatusText: any) => { 57 | callback(log, subXhr.status !== 404 ? subXhr.responseText : undefined); 58 | } 59 | }) 60 | } else { 61 | callback(log, xhr.responseText); 62 | } 63 | } 64 | }); 65 | } 66 | } 67 | }) 68 | .on('error', (err: any) => { 69 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 70 | callback(); 71 | }); 72 | } 73 | 74 | getLatestVersion(packageName: string, callback: any) { 75 | bower.commands.info(packageName, undefined, {}) 76 | .on('end', (result: any) => { 77 | callback(result.latest.version); 78 | }) 79 | .on('error', (err: any) => { 80 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 81 | callback(); 82 | }); 83 | } 84 | 85 | getSearchResult(query: string, callback: any) { 86 | bower.commands.search(query, {}) 87 | .on('end', callback) 88 | .on('error', (err: any) => { 89 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 90 | callback(); 91 | }); 92 | } 93 | 94 | install(packages: IPackageCommand, callback: any) { 95 | const fileDir: string = packages.packagePath.replace('\\bower.json', ''); 96 | 97 | bower.commands.install(packages.packages, { forceLatest: true, save: true }, { cwd: fileDir, force: true, newly: true }) 98 | .on('end', callback) 99 | .on('error', (err: any) => { 100 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 101 | callback(); 102 | }); 103 | } 104 | 105 | uninstall(packages: IPackageCommand, callback: any) { 106 | const fileDir: string = packages.packagePath.replace('\\bower.json', ''); 107 | bower.commands.uninstall(packages.packages, { forceLatest: true, save: true, saveDev: true }, { cwd: fileDir, force: true, newly: true }) 108 | .on('end', callback) 109 | .on('error', (err: any) => { 110 | new MessageDialogHelpers().error(err.message, 7500, 'top'); 111 | callback(); 112 | }); 113 | } 114 | 115 | update(packages: IPackageCommand, callback: any) { 116 | this.install(packages, callback); 117 | } 118 | 119 | downgrade(packages: IPackageCommand, callback: any) { 120 | this.install(packages, callback); 121 | } 122 | } -------------------------------------------------------------------------------- /js/directives/PackageDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var PackageHelpers_1 = require("../helpers/PackageHelpers"); 4 | var PackageDirective = (function () { 5 | function PackageDirective() { 6 | this.restrict = 'E'; 7 | this.templateUrl = './templates/packages.html'; 8 | this.transclude = true; 9 | } 10 | PackageDirective.prototype.link = function (scope, element, attrs) { 11 | scope.makeFilter = function (command) { 12 | scope.$root.searchVal = command + " "; 13 | $('.js-package-search').focus(); 14 | }; 15 | scope.clearSearch = function () { 16 | scope.$root.searchVal = ''; 17 | $('.js-package-search').focus(); 18 | }; 19 | scope.$root.getFilteredData = function () { 20 | var queryVal = scope.$root.searchVal; 21 | if (queryVal === '' || queryVal === null) { 22 | scope.$root.packageList = new PackageHelpers_1.PackageHelpers(scope).getAllInstalledPackages(); 23 | } 24 | else if (queryVal.indexOf('@installed') > -1) { 25 | var query_1 = queryVal.replace('@installed', '').trim(); 26 | var installedPackages = new PackageHelpers_1.PackageHelpers(scope).getAllInstalledPackages(); 27 | if (query_1 !== '') { 28 | installedPackages = $.grep(installedPackages, function (key, i) { 29 | return key.name.indexOf(query_1) > -1; 30 | }); 31 | } 32 | scope.$root.packageList = installedPackages; 33 | } 34 | else if (queryVal.indexOf('@update') > -1) { 35 | var query_2 = queryVal.replace('@update', '').trim(); 36 | var installedPackages = new PackageHelpers_1.PackageHelpers(scope).getAllInstalledPackages(); 37 | var updateAvailablePackages = $.grep(installedPackages, function (key, i) { 38 | return scope.$root.packages[key.name].listItemControl.update === true; 39 | }); 40 | if (query_2 !== '') { 41 | updateAvailablePackages = $.grep(updateAvailablePackages, function (key, i) { 42 | return key.name.indexOf(query_2) > -1; 43 | }); 44 | } 45 | scope.$root.packageList = updateAvailablePackages; 46 | } 47 | else if (queryVal.indexOf('@devdependencies') > -1) { 48 | var query_3 = queryVal.replace('@devdependencies', '').trim(); 49 | var installedPackages = new PackageHelpers_1.PackageHelpers(scope).getAllInstalledPackages(); 50 | var packs = $.grep(installedPackages, function (key, i) { 51 | return scope.$root.packages[key.name].isDevDependencies === true; 52 | }); 53 | if (query_3 !== '') { 54 | packs = $.grep(packs, function (key, i) { 55 | return key.name.indexOf(query_3) > -1; 56 | }); 57 | } 58 | scope.$root.packageList = packs; 59 | } 60 | else if (queryVal.indexOf('@dependencies') > -1) { 61 | var query_4 = queryVal.replace('@dependencies', '').trim(); 62 | var installedPackages = new PackageHelpers_1.PackageHelpers(scope).getAllInstalledPackages(); 63 | var packs = $.grep(installedPackages, function (key, i) { 64 | return scope.$root.packages[key.name].isDevDependencies === false; 65 | }); 66 | if (query_4 !== '') { 67 | packs = $.grep(packs, function (key, i) { 68 | return key.name.indexOf(query_4) > -1; 69 | }); 70 | } 71 | scope.$root.packageList = packs; 72 | } 73 | else { 74 | scope.$root.showInputLoader = true; 75 | new PackageHelpers_1.PackageHelpers(scope).getSearchResult(queryVal, function (result) { 76 | scope.$root.$apply(function () { 77 | scope.$root.packageList = result; 78 | scope.$root.showInputLoader = false; 79 | }); 80 | }); 81 | } 82 | }; 83 | scope.$root.$watch('searchVal', function (newVal, oldVal) { 84 | if (newVal !== undefined) 85 | scope.$root.getFilteredData(); 86 | }); 87 | scope.$root.reloadPackageList = function () { 88 | var activeItem = scope.$root.activePackageExplorerItem; 89 | scope.$root.hidePackageDetailOverlay = false; 90 | scope.$root.packageList = {}; 91 | scope.$root.showLoader = true; 92 | scope.$root.searchVal = ''; 93 | new PackageHelpers_1.PackageHelpers(scope).resetPackages(); 94 | new PackageHelpers_1.PackageHelpers(scope).getInstalledPackagesFromFile(activeItem.packageManager, activeItem.path, function (result) { 95 | scope.$root.$apply(function () { 96 | scope.$root.hidePackageOverlay = true; 97 | if (result.length === 0) { 98 | scope.$root.showLoader = false; 99 | } 100 | else { 101 | scope.$root.loadedPackageLength = result.length; 102 | } 103 | scope.$root.packageList = result; 104 | }); 105 | }); 106 | }; 107 | }; 108 | return PackageDirective; 109 | }()); 110 | exports.PackageDirective = PackageDirective; 111 | -------------------------------------------------------------------------------- /js/services/NpmService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var MessageDialogHelpers_1 = require("../helpers/MessageDialogHelpers"); 4 | var childProcess = require('child_process'); 5 | var NpmService = (function () { 6 | function NpmService() { 7 | } 8 | NpmService.prototype.getGlobalPackages = function (callback) { 9 | childProcess.exec('npm ls -g --depth=0 --json', { maxBuffer: 1024 * 500 }, function (error, stdout, stderr) { 10 | var result = []; 11 | var response = JSON.parse(stdout).dependencies; 12 | $.each(response, function (key, value) { 13 | result.push({ 14 | name: key, 15 | version: value.version 16 | }); 17 | }); 18 | setTimeout(callback(result), 250); 19 | }); 20 | }; 21 | NpmService.prototype.getInstalledPackagesFromFile = function (filePath, callback) { 22 | filePath = filePath.replace('\\package.json', ''); 23 | childProcess.exec("npm ls --depth=0 --json", { cwd: filePath, maxBuffer: 1024 * 500 }, function (error, stdout, stderr) { 24 | callback(JSON.parse(stdout)); 25 | }); 26 | }; 27 | NpmService.prototype.getPackageDetailInfo = function (packageName, callback) { 28 | childProcess.exec("npm info " + packageName + " --json", { maxBuffer: 1024 * 500 }, function (error, stdout, stderr) { 29 | callback(JSON.parse(stdout)); 30 | }); 31 | }; 32 | NpmService.prototype.getPackageDetailInfoByVersion = function (packageName, version, callback) { 33 | childProcess.exec("npm info " + packageName + "@" + version + " --json", { maxBuffer: 1024 * 500 }, function (error, stdout, stderr) { 34 | var parsedData = JSON.parse(stdout); 35 | var userReposStr = parsedData.repository.url.replace('git+https://github.com/', '').replace('.git', '').replace('https://github.com/', ''); 36 | var readMeUrl = "https://raw.githubusercontent.com/" + userReposStr + "/"; 37 | $.ajax({ 38 | url: readMeUrl + "v" + parsedData.version + "/README.md", 39 | type: 'GET', 40 | data: {}, 41 | complete: function (xhr, statusText) { 42 | if (xhr.status === 404) { 43 | $.ajax({ 44 | url: "" + readMeUrl + parsedData.version + "/README.md", 45 | type: 'GET', 46 | data: {}, 47 | complete: function (subXhr, subStatusText) { 48 | callback(parsedData, subXhr.status !== 404 ? subXhr.responseText : undefined); 49 | } 50 | }); 51 | } 52 | else { 53 | callback(parsedData, xhr.responseText); 54 | } 55 | } 56 | }); 57 | }); 58 | }; 59 | NpmService.prototype.getLatestVersion = function (packageName, callback) { 60 | childProcess.exec("npm view " + packageName + " version --json", function (error, stdout, stderr) { 61 | callback(JSON.parse(stdout)); 62 | }); 63 | }; 64 | NpmService.prototype.getSearchResult = function (query, callback) { 65 | childProcess.exec("npm search " + query + " --no-description --json", function (error, stdout, stderr) { 66 | callback(JSON.parse(stdout)); 67 | }); 68 | }; 69 | NpmService.prototype.install = function (packages, callback) { 70 | var installOptions = { 71 | maxBuffer: 1024 * 500 72 | }; 73 | var command = "npm install " + packages.packages.join(' '); 74 | if (packages.isGlobal) { 75 | command += ' -g'; 76 | } 77 | else { 78 | command += ' --save'; 79 | if (packages.isDevDependency) 80 | command += '-dev'; 81 | installOptions['cwd'] = packages.packagePath.replace('\\package.json', ''); 82 | } 83 | command += ' --force --json'; 84 | childProcess.exec(command, installOptions, function (err, stdout, stderr) { 85 | if (err) { 86 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 87 | return; 88 | } 89 | callback(); 90 | }); 91 | }; 92 | NpmService.prototype.uninstall = function (packages, callback) { 93 | var uninstallOptions = { 94 | maxBuffer: 1024 * 500 95 | }; 96 | var command = "npm uninstall " + packages.packages.join(' '); 97 | if (packages.isGlobal) { 98 | command += ' -g'; 99 | } 100 | else { 101 | command += ' --save'; 102 | if (packages.isDevDependency) 103 | command += '-dev'; 104 | uninstallOptions['cwd'] = packages.packagePath.replace('\\package.json', ''); 105 | } 106 | command += ' --force --json'; 107 | childProcess.exec(command, uninstallOptions, function (err, stdout, stderr) { 108 | if (err) { 109 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 110 | callback(); 111 | } 112 | callback(); 113 | }); 114 | }; 115 | NpmService.prototype.update = function (packages, callback) { 116 | this.install(packages, callback); 117 | }; 118 | NpmService.prototype.downgrade = function (packages, callback) { 119 | this.install(packages, callback); 120 | }; 121 | return NpmService; 122 | }()); 123 | exports.NpmService = NpmService; 124 | -------------------------------------------------------------------------------- /js/services/BowerService.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var MessageDialogHelpers_1 = require("../helpers/MessageDialogHelpers"); 4 | var childProcess = require('child_process'); 5 | var bower = require('bower'); 6 | var fs = require('fs'); 7 | var BowerService = (function () { 8 | function BowerService() { 9 | } 10 | BowerService.prototype.getInstalledPackagesFromFile = function (filePath, callback) { 11 | filePath = filePath.replace('\\bower.json', ''); 12 | bower.commands.list({}, { 'cwd': filePath, 'offline': true }) 13 | .on('end', callback) 14 | .on('error', function (err) { 15 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 16 | callback(); 17 | }); 18 | }; 19 | BowerService.prototype.getPackageDetailInfo = function (packageName, callback) { 20 | bower.commands.info(packageName, undefined, {}) 21 | .on('end', callback) 22 | .on('error', function (err) { 23 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 24 | callback(); 25 | }); 26 | }; 27 | BowerService.prototype.getPackageDetailByVersion = function (packageName, version, callback) { 28 | bower.commands.info(packageName + "#" + version, undefined, {}) 29 | .on('log', function (log) { 30 | if (log.level === 'info') { 31 | var userReposStr = log.data.resolver.source.replace('https://github.com/', '').replace('.git', ''); 32 | var readMeUrl_1 = "https://raw.githubusercontent.com/" + userReposStr + "/"; 33 | if (log.data.pkgMeta !== undefined && log.data.pkgMeta._resolution !== undefined) { 34 | $.ajax({ 35 | url: "" + readMeUrl_1 + log.data.pkgMeta._resolution.tag + "/README.md", 36 | type: 'GET', 37 | data: {}, 38 | complete: function (xhr, statusText) { 39 | callback(log, xhr.status !== 404 ? xhr.responseText : undefined); 40 | } 41 | }); 42 | } 43 | else { 44 | $.ajax({ 45 | url: readMeUrl_1 + "v" + log.data.endpoint.target + "/README.md", 46 | type: 'GET', 47 | data: {}, 48 | complete: function (xhr, statusText) { 49 | if (xhr.status === 404) { 50 | $.ajax({ 51 | url: "" + readMeUrl_1 + log.data.endpoint.target + "/README.md", 52 | type: 'GET', 53 | data: {}, 54 | complete: function (subXhr, subStatusText) { 55 | callback(log, subXhr.status !== 404 ? subXhr.responseText : undefined); 56 | } 57 | }); 58 | } 59 | else { 60 | callback(log, xhr.responseText); 61 | } 62 | } 63 | }); 64 | } 65 | } 66 | }) 67 | .on('error', function (err) { 68 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 69 | callback(); 70 | }); 71 | }; 72 | BowerService.prototype.getLatestVersion = function (packageName, callback) { 73 | bower.commands.info(packageName, undefined, {}) 74 | .on('end', function (result) { 75 | callback(result.latest.version); 76 | }) 77 | .on('error', function (err) { 78 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 79 | callback(); 80 | }); 81 | }; 82 | BowerService.prototype.getSearchResult = function (query, callback) { 83 | bower.commands.search(query, {}) 84 | .on('end', callback) 85 | .on('error', function (err) { 86 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 87 | callback(); 88 | }); 89 | }; 90 | BowerService.prototype.install = function (packages, callback) { 91 | var fileDir = packages.packagePath.replace('\\bower.json', ''); 92 | bower.commands.install(packages.packages, { forceLatest: true, save: true }, { cwd: fileDir, force: true, newly: true }) 93 | .on('end', callback) 94 | .on('error', function (err) { 95 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 96 | callback(); 97 | }); 98 | }; 99 | BowerService.prototype.uninstall = function (packages, callback) { 100 | var fileDir = packages.packagePath.replace('\\bower.json', ''); 101 | bower.commands.uninstall(packages.packages, { forceLatest: true, save: true, saveDev: true }, { cwd: fileDir, force: true, newly: true }) 102 | .on('end', callback) 103 | .on('error', function (err) { 104 | new MessageDialogHelpers_1.MessageDialogHelpers().error(err.message, 7500, 'top'); 105 | callback(); 106 | }); 107 | }; 108 | BowerService.prototype.update = function (packages, callback) { 109 | this.install(packages, callback); 110 | }; 111 | BowerService.prototype.downgrade = function (packages, callback) { 112 | this.install(packages, callback); 113 | }; 114 | return BowerService; 115 | }()); 116 | exports.BowerService = BowerService; 117 | -------------------------------------------------------------------------------- /js/directives/PackageDetailDirective.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var PackageHelpers_1 = require("../helpers/PackageHelpers"); 4 | var WindowHelpers_1 = require("../helpers/WindowHelpers"); 5 | var compareVersions = require('compare-versions'); 6 | var PackageDetail = (function () { 7 | function PackageDetail() { 8 | this.restrict = 'E'; 9 | this.templateUrl = './templates/package-detail.html'; 10 | } 11 | PackageDetail.prototype.link = function (scope, element, attrs) { 12 | scope.$root.$watch('activePackageItem', function (newVal, oldVal) { 13 | if (newVal !== undefined) { 14 | scope.$root.showLoader = true; 15 | var packageName_1 = newVal.name; 16 | new PackageHelpers_1.PackageHelpers(scope).getPackageDetailInfo(packageName_1, function (result) { 17 | scope.$apply(function () { 18 | var latestVersion = scope.$root.packages[packageName_1].latestVersion; 19 | if (latestVersion !== undefined && latestVersion !== null && latestVersion !== '') { 20 | scope.$root.packages[packageName_1].selectedVersion = latestVersion; 21 | } 22 | else { 23 | scope.$root.packages[packageName_1].selectedVersion = 24 | scope.$root.packages[packageName_1].latestVersion = 25 | scope.$root.packages[packageName_1].version = 26 | result.versions[0]; 27 | } 28 | scope.packageInfo = result; 29 | scope.packageInfo.version = scope.$root.packages[packageName_1].version; 30 | scope.$root.hidePackageDetailOverlay = true; 31 | }); 32 | setTimeout(function () { 33 | scope.getDetailInfo(packageName_1, newVal.selectedVersion); 34 | }, 500); 35 | }); 36 | } 37 | }); 38 | scope.$root.packageCommand = function ($event, packageName) { 39 | var $packageContainer = $("[data-package=\"" + packageName + "\"]"); 40 | var cmd = $($event.target).data('cmd'); 41 | var $commandBtn = $packageContainer.find("[data-cmd^=\"" + (cmd === 'installAsDev' ? 'install' : cmd) + "\"]"); 42 | var $btn = null; 43 | if (cmd !== 'reload') { 44 | $btn = $commandBtn.button('loading'); 45 | } 46 | var pack = scope.$root.packages[packageName]; 47 | new PackageHelpers_1.PackageHelpers(scope).runCommand(cmd, pack, function () { 48 | if ($btn !== null) 49 | $btn.button('reset'); 50 | pack.listItemControl.reload = true; 51 | pack.listItemControl.downgrade = false; 52 | pack.listItemControl.update = false; 53 | pack.listItemControl.loader = false; 54 | if (cmd === 'install' || cmd === 'installAsDev') { 55 | pack.listItemControl.install = false; 56 | pack.listItemControl.uninstall = true; 57 | pack.detailControl.install = false; 58 | pack.detailControl.uninstall = true; 59 | } 60 | else if (cmd === 'uninstall') { 61 | pack.listItemControl.install = true; 62 | pack.listItemControl.uninstall = false; 63 | pack.detailControl.install = true; 64 | pack.detailControl.uninstall = false; 65 | } 66 | else if (cmd === 'reload') { 67 | scope.$root.reloadPackageList(); 68 | } 69 | pack.detailControl.reload = true; 70 | pack.detailControl.downgrade = false; 71 | pack.detailControl.update = false; 72 | pack.detailControl.loader = false; 73 | $btn.button('reset'); 74 | scope.$apply(function () { scope.$root.packages[packageName] = pack; }); 75 | }); 76 | }; 77 | scope.onVersionChanged = function () { 78 | var activePackageItem = scope.$root.activePackageItem; 79 | scope.$root.showLoader = true; 80 | if (activePackageItem.listItemControl.install === false) { 81 | var compareResult = compareVersions(activePackageItem.selectedVersion, activePackageItem.version); 82 | activePackageItem.detailControl.update = compareResult > 0; 83 | activePackageItem.detailControl.downgrade = compareResult < 0; 84 | } 85 | scope.$root.activePackageItem = activePackageItem; 86 | scope.getDetailInfo(activePackageItem.name, activePackageItem.selectedVersion); 87 | }; 88 | scope.getDetailInfo = function (packageName, version) { 89 | new PackageHelpers_1.PackageHelpers(scope).getPackageDetailByVersion(packageName, version, function (log, readMe) { 90 | scope.$apply(function () { 91 | var versions = scope.packageInfo.versions; 92 | scope.packageInfo = log; 93 | scope.packageInfo.versions = versions; 94 | scope.packageInfo.readMe = readMe; 95 | scope.$root.showLoader = false; 96 | }); 97 | new WindowHelpers_1.WindowHelpers().setPackageDetailContentHeight(); 98 | setTimeout(function () { $('#details a:not(.scroll-to-top)').attr('target', '_blank'); }, 1000); 99 | }); 100 | }; 101 | }; 102 | return PackageDetail; 103 | }()); 104 | exports.PackageDetail = PackageDetail; 105 | -------------------------------------------------------------------------------- /src/js/directives/PackageDetailDirective.ts: -------------------------------------------------------------------------------- 1 | import { PackageHelpers } from '../helpers/PackageHelpers'; 2 | import { WindowHelpers } from '../helpers/WindowHelpers'; 3 | import { IPackage } from '../interfaces/IPackage'; 4 | import { IPackageDetail } from '../interfaces/IPackageDetail'; 5 | const compareVersions = require('compare-versions'); 6 | 7 | export class PackageDetail { 8 | restrict: string; 9 | templateUrl: string; 10 | 11 | constructor() { 12 | this.restrict = 'E' 13 | this.templateUrl = './templates/package-detail.html' 14 | } 15 | 16 | link(scope: any, element: any, attrs: any) { 17 | scope.$root.$watch('activePackageItem', (newVal: any, oldVal: any) => { 18 | if (newVal !== undefined) { 19 | scope.$root.showLoader = true; 20 | const packageName: string = newVal.name; 21 | 22 | new PackageHelpers(scope).getPackageDetailInfo(packageName, (result: any) => { 23 | scope.$apply(() => { 24 | const latestVersion: string = scope.$root.packages[packageName].latestVersion; 25 | 26 | if (latestVersion !== undefined && latestVersion !== null && latestVersion !== '') { 27 | scope.$root.packages[packageName].selectedVersion = latestVersion; 28 | } else { 29 | scope.$root.packages[packageName].selectedVersion = 30 | scope.$root.packages[packageName].latestVersion = 31 | scope.$root.packages[packageName].version = 32 | result.versions[0]; 33 | } 34 | scope.packageInfo = result; 35 | scope.packageInfo.version = scope.$root.packages[packageName].version; 36 | scope.$root.hidePackageDetailOverlay = true; 37 | }); 38 | 39 | setTimeout(() => { 40 | scope.getDetailInfo(packageName, newVal.selectedVersion); 41 | }, 500); 42 | }) 43 | } 44 | }); 45 | 46 | scope.$root.packageCommand = ($event: any, packageName: string) => { 47 | const $packageContainer = $(`[data-package="${packageName}"]`); 48 | const cmd: string = $($event.target).data('cmd'); 49 | const $commandBtn = $packageContainer.find(`[data-cmd^="${cmd === 'installAsDev' ? 'install' : cmd}"]`); 50 | let $btn: any = null; 51 | if (cmd !== 'reload') { 52 | $btn = $commandBtn.button('loading'); 53 | } 54 | 55 | var pack: IPackage = scope.$root.packages[packageName]; 56 | new PackageHelpers(scope).runCommand(cmd, pack, () => { 57 | if ($btn !== null) $btn.button('reset'); 58 | 59 | //Buttons 60 | pack.listItemControl.reload = true; 61 | pack.listItemControl.downgrade = false; 62 | pack.listItemControl.update = false; 63 | pack.listItemControl.loader = false; 64 | 65 | if (cmd === 'install' || cmd === 'installAsDev') { 66 | pack.listItemControl.install = false; 67 | pack.listItemControl.uninstall = true; 68 | 69 | pack.detailControl.install = false; 70 | pack.detailControl.uninstall = true; 71 | } else if (cmd === 'uninstall') { 72 | pack.listItemControl.install = true; 73 | pack.listItemControl.uninstall = false; 74 | 75 | pack.detailControl.install = true; 76 | pack.detailControl.uninstall = false; 77 | } else if (cmd === 'reload') { 78 | scope.$root.reloadPackageList(); 79 | } 80 | 81 | pack.detailControl.reload = true; 82 | pack.detailControl.downgrade = false; 83 | pack.detailControl.update = false; 84 | pack.detailControl.loader = false; 85 | 86 | $btn.button('reset'); 87 | scope.$apply(() => { scope.$root.packages[packageName] = pack; }); 88 | }); 89 | } 90 | 91 | scope.onVersionChanged = function () { 92 | const activePackageItem: IPackage = scope.$root.activePackageItem; 93 | scope.$root.showLoader = true; 94 | 95 | if (activePackageItem.listItemControl.install === false) { 96 | const compareResult: number = compareVersions(activePackageItem.selectedVersion, activePackageItem.version); 97 | 98 | activePackageItem.detailControl.update = compareResult > 0; 99 | activePackageItem.detailControl.downgrade = compareResult < 0; 100 | } 101 | 102 | scope.$root.activePackageItem = activePackageItem; 103 | 104 | scope.getDetailInfo(activePackageItem.name, activePackageItem.selectedVersion); 105 | // new PackageHelpers(scope).getPackageDetailInfo(activePackageItem.name, activePackageItem.selectedVersion, (result: any) => { 106 | // scope.$apply(() => { 107 | // scope.packageInfo.author = result.author; 108 | // scope.packageInfo.description = result.description; 109 | // scope.packageInfo.license = typeof result.license === 'object' ? result.license.type : result.license; 110 | // scope.packageInfo.contributors = result.contributors; 111 | // scope.packageInfo.dependencies = result.dependencies; 112 | // scope.packageInfo.devDependencies = result.devDependencies; 113 | // scope.packageInfo.version = activePackageItem.selectedVersion; 114 | 115 | // scope.$root.showLoader = false; 116 | // }); 117 | // }); 118 | } 119 | 120 | scope.getDetailInfo = (packageName: string, version: string) => { 121 | new PackageHelpers(scope).getPackageDetailByVersion(packageName, version, (log: IPackageDetail, readMe: any) => { 122 | scope.$apply(() => { 123 | const versions: string[] = scope.packageInfo.versions; 124 | scope.packageInfo = log; 125 | scope.packageInfo.versions = versions; 126 | scope.packageInfo.readMe = readMe; 127 | scope.$root.showLoader = false; 128 | }); 129 | 130 | new WindowHelpers().setPackageDetailContentHeight(); 131 | setTimeout(() => { $('#details a:not(.scroll-to-top)').attr('target', '_blank'); }, 1000); 132 | }) 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /templates/package-detail.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | | 5 | 6 |
7 |
8 | 11 |
12 | 13 | 18 | 22 |
23 | 25 | 27 | 29 | 31 | 33 |
34 |
35 |
36 |
37 | 42 |
43 |
44 |
No Details
45 |
46 |
47 |
48 |
No Contributors
49 |
50 | 51 | 52 | 53 | 54 | 55 | 56 |
57 |
58 |
59 |
60 |
No Dependencies
61 |
62 |

Dependencies

63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
71 |
72 | 73 |
74 |

Dev Dependencies

75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 |
83 |
84 |
85 |
86 |
87 |
88 |
-------------------------------------------------------------------------------- /images/activity-bar-icons/bower.svg: -------------------------------------------------------------------------------- 1 | bower-logo -------------------------------------------------------------------------------- /src/scss/_packages.scss: -------------------------------------------------------------------------------- 1 | @import '_mixins'; 2 | 3 | .workbench-container { 4 | .packages { 5 | .title { 6 | font-size: 13px; 7 | height: 36px; 8 | line-height: 36px; 9 | padding-left: 10px; 10 | padding-right: 10px; 11 | 12 | span { 13 | img { 14 | max-width: 32px; 15 | margin-right: 3px; 16 | } 17 | } 18 | } 19 | } 20 | 21 | package-list { 22 | height: calc(100% - 90px); 23 | overflow-y: auto; 24 | display: block; 25 | } 26 | 27 | packages { 28 | height: 100%; 29 | } 30 | 31 | .packages { 32 | height: 100%; 33 | 34 | .content { 35 | height: 100%; 36 | } 37 | 38 | .content { 39 | .content-split-pane { 40 | .split-pane-component { 41 | &:first-child { 42 | min-width: 320px; 43 | } 44 | 45 | &:last-child { 46 | min-width: 320px; 47 | } 48 | 49 | hr { 50 | margin: 0; 51 | padding: 0; 52 | display: block; 53 | height: 1px; 54 | } 55 | 56 | .search-no-result { 57 | font-size: 13px; 58 | text-align: center; 59 | margin-top: 8px; 60 | } 61 | 62 | .title { 63 | .btn-icon { 64 | background: transparent; 65 | border: none; 66 | font-size: 17px; 67 | padding: 0 5px; 68 | margin-right: -5px; 69 | position: relative; 70 | top: -2px; 71 | 72 | &.btn-refresh { 73 | font-size: 16px; 74 | position: relative; 75 | top: 0px; 76 | margin-left: 3px; 77 | } 78 | } 79 | } 80 | } 81 | } 82 | 83 | .package-list { 84 | padding: 0; 85 | margin: 0; 86 | list-style: none; 87 | 88 | li { 89 | .package-list-item { 90 | display: block; 91 | padding: 10px 12px; 92 | font-size: 13px; 93 | text-decoration: none; 94 | position: relative; 95 | cursor: pointer; 96 | 97 | .package-version, 98 | .package-dev { 99 | font-size: 9px; 100 | padding: 1px 3px 0 3px; 101 | border-radius: 3px; 102 | font-weight: bold; 103 | margin-left: 2px; 104 | } 105 | } 106 | } 107 | } 108 | } 109 | } 110 | 111 | .nav-tabs { 112 | height: 36px; 113 | 114 | > li { 115 | > a { 116 | border-radius: 0; 117 | font-size: 13px; 118 | margin-right: 0; 119 | } 120 | } 121 | } 122 | 123 | .nav { 124 | > li { 125 | a { 126 | padding: 7px 12px; 127 | height: 36px; 128 | } 129 | } 130 | } 131 | 132 | .clearable-input { 133 | .fa { 134 | position: absolute; 135 | top: 8px; 136 | right: 8px; 137 | font-size: 15px; 138 | cursor: pointer; 139 | } 140 | } 141 | 142 | .package-detail-container { 143 | .header { 144 | padding: 15px 20px; 145 | 146 | .title { 147 | font-weight: 600; 148 | font-size: 18px; 149 | padding-left: 0; 150 | border: none !important; 151 | 152 | span { 153 | &:last-child { 154 | font-size: 9px; 155 | padding: 0 3px; 156 | border-radius: 3px; 157 | font-weight: bold; 158 | position: relative; 159 | top: -1px; 160 | } 161 | } 162 | } 163 | 164 | .author { 165 | font-size: 13px; 166 | } 167 | 168 | .license { 169 | font-size: 13px; 170 | } 171 | 172 | .description { 173 | font-size: 13px; 174 | margin-top: 20px; 175 | } 176 | } 177 | } 178 | 179 | .package-detail-info-container { 180 | .read-me-container { 181 | font-size: 13px; 182 | 183 | h1 { 184 | font-size: 17px; 185 | margin-top: 40px; 186 | font-weight: 600; 187 | 188 | &:first-child { 189 | margin-top: 0 !important; 190 | } 191 | } 192 | 193 | h2 { 194 | font-size: 16px; 195 | margin-top: 40px; 196 | font-weight: 600; 197 | } 198 | 199 | h3 { 200 | font-size: 15px; 201 | margin-top: 40px; 202 | font-weight: 600; 203 | } 204 | 205 | h4 { 206 | font-size: 14px; 207 | margin-top: 40px; 208 | font-weight: 600; 209 | } 210 | 211 | h5 { 212 | font-size: 13px; 213 | margin-top: 40px; 214 | font-weight: 600; 215 | } 216 | 217 | h6 { 218 | font-size: 12px; 219 | margin-top: 40px; 220 | font-weight: 600; 221 | } 222 | 223 | pre { 224 | border-radius: 0; 225 | border: none; 226 | padding: 15px 10px; 227 | } 228 | 229 | code { 230 | border-radius: 0; 231 | padding: 2px 6px; 232 | } 233 | 234 | blockquote { 235 | font-size: 14px; 236 | margin: 25px 0; 237 | } 238 | 239 | img { 240 | max-width: 100%; 241 | } 242 | 243 | hr { 244 | margin: 10px 0 !important; 245 | } 246 | } 247 | 248 | .no-info { 249 | font-size: 13px; 250 | } 251 | 252 | #details { 253 | padding: 15px; 254 | } 255 | 256 | #dependencies { 257 | font-size: 13px; 258 | padding: 15px; 259 | 260 | h1 { 261 | font-size: 16px; 262 | margin-top: 0; 263 | } 264 | } 265 | 266 | #contributors { 267 | font-size: 13px; 268 | padding: 15px; 269 | 270 | h1 { 271 | font-size: 14px; 272 | margin-top: 0; 273 | margin-bottom: 10px; 274 | } 275 | } 276 | 277 | .table { 278 | > tbody { 279 | tr { 280 | td { 281 | border-top: none; 282 | } 283 | } 284 | } 285 | } 286 | } 287 | 288 | .setup-container { 289 | margin-top: 17px; 290 | 291 | select { 292 | &.form-control { 293 | width: auto; 294 | display: inline-block; 295 | height: auto; 296 | font-size: 12px; 297 | padding: 3.5px 5px 3.5px 5px; 298 | } 299 | } 300 | } 301 | } 302 | 303 | loader { 304 | z-index: 9999; 305 | position: fixed; 306 | top: 0; 307 | left: 0; 308 | width: 100%; 309 | height: 100%; 310 | 311 | .loader { 312 | max-width: 180px; 313 | width: 100%; 314 | padding: 25px; 315 | text-align: center; 316 | position: absolute; 317 | left: calc(50% - 90px); 318 | top: calc(50% - 49px); 319 | border-radius: 3px; 320 | 321 | p { 322 | margin-top: 10px; 323 | margin-bottom: 0; 324 | font-size: 13px; 325 | } 326 | } 327 | } 328 | 329 | .form-horizontal { 330 | label { 331 | font-weight: normal; 332 | font-size: 13px; 333 | } 334 | } 335 | 336 | .advanced-options { 337 | margin-top: 20px; 338 | 339 | .option-header { 340 | a { 341 | font-weight: bold; 342 | font-size: 13px; 343 | text-decoration: none; 344 | 345 | &:before { 346 | font-family: 'FontAwesome'; 347 | content: '\f0da'; 348 | width: 12px; 349 | display: inline-block; 350 | } 351 | } 352 | } 353 | 354 | .option-content { 355 | height: 0; 356 | overflow: hidden; 357 | margin-top: 20px; 358 | 359 | h3 { 360 | font-size: 13px; 361 | font-weight: 600; 362 | margin-top: 20px; 363 | } 364 | } 365 | 366 | &.open { 367 | .option-header { 368 | a { 369 | &:before { 370 | content: '\f0d7'; 371 | } 372 | } 373 | } 374 | 375 | .option-content { 376 | height: auto; 377 | margin-bottom: -15px; 378 | } 379 | } 380 | } 381 | 382 | .dropdown-menu { 383 | margin-top: -8px; 384 | border-radius: 0; 385 | 386 | > li { 387 | > a { 388 | padding: 5px 10px; 389 | font-size: 13px; 390 | } 391 | } 392 | } 393 | 394 | .package-detail-pane { 395 | overflow: hidden !important; 396 | 397 | .package-detail-container { 398 | .package-detail-info-container { 399 | .tab-content { 400 | .tab-pane { 401 | overflow: auto; 402 | } 403 | } 404 | } 405 | } 406 | } 407 | 408 | .scroll-to-top { 409 | position: absolute; 410 | bottom: 10px; 411 | right: 20px; 412 | padding: 6px 10px; 413 | font-size: 18px; 414 | } 415 | 416 | .package-overlay, 417 | .package-detail-overlay { 418 | position: absolute; 419 | top: 0; 420 | left: 0; 421 | right: 0; 422 | bottom: 0; 423 | width: 100%; 424 | height: 100%; 425 | z-index: 99; 426 | text-align: center; 427 | 428 | p { 429 | position: relative; 430 | top: 12px; 431 | font-size: 13px; 432 | } 433 | } 434 | --------------------------------------------------------------------------------