Compare commits
164 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31ca6f4a78 | ||
|
|
1f9bc3a2d3 | ||
|
|
aad81bedbd | ||
|
|
1158c5fc1d | ||
|
|
a9727b990d | ||
|
|
a9f94a2cfa | ||
|
|
eb0b9bfc40 | ||
|
|
b4e1a99add | ||
|
|
c21d3ff504 | ||
|
|
2957d95133 | ||
|
|
d6ce727b0c | ||
|
|
c18c9fadd1 | ||
|
|
dce33716d9 | ||
|
|
cf8ba61943 | ||
|
|
26383aa79d | ||
|
|
136bd77d5f | ||
|
|
ba6620f040 | ||
|
|
4a8e7b7dc8 | ||
|
|
6ca48eb537 | ||
|
|
2864a098ab | ||
|
|
fec0cceba6 | ||
|
|
3bf39ce1b0 | ||
|
|
3a047b5bbe | ||
|
|
50145d4d1a | ||
|
|
4df2e8a48b | ||
|
|
3dae451776 | ||
|
|
4d038f37b3 | ||
|
|
a09ef4df65 | ||
|
|
628862d024 | ||
|
|
af83be1fcc | ||
|
|
05cb5527e3 | ||
|
|
7d910a0f75 | ||
|
|
ab74f6426e | ||
|
|
390bb8ff67 | ||
|
|
fcd108f9e7 | ||
|
|
dd2c6ee3d2 | ||
|
|
9917425cc8 | ||
|
|
3f54ca11a1 | ||
|
|
e059f800d6 | ||
|
|
f2dec10c05 | ||
|
|
d8117eac7d | ||
|
|
354514818c | ||
|
|
4ac814be93 | ||
|
|
2f7387a67f | ||
|
|
1cf779c5a6 | ||
|
|
64c9a75d92 | ||
|
|
5a8c4e6a9b | ||
|
|
2fd728b5e8 | ||
|
|
9bda1672d5 | ||
|
|
101eade38f | ||
|
|
6a1c8bcd75 | ||
|
|
c49a09e721 | ||
|
|
d526ded04b | ||
|
|
06344bee72 | ||
|
|
f9f67ff9ea | ||
|
|
9e519166d5 | ||
|
|
1b649bbe96 | ||
|
|
9ed305c08b | ||
|
|
dfebfa20a2 | ||
|
|
564c81362e | ||
|
|
d938ea3ef1 | ||
|
|
beceb476d9 | ||
|
|
ca882e4568 | ||
|
|
227c626c3a | ||
|
|
c3606e3c3e | ||
|
|
ae9ffccf65 | ||
|
|
897dcb8c3b | ||
|
|
38e1fdeeda | ||
|
|
c94e587675 | ||
|
|
5354dad9fe | ||
|
|
cbbab432e4 | ||
|
|
e21ab82729 | ||
|
|
987a98732a | ||
|
|
3ddfda80ed | ||
|
|
3e5da523ce | ||
|
|
6f6625d3db | ||
|
|
e9b4331d60 | ||
|
|
b7e5b70df7 | ||
|
|
ec04a20b8d | ||
|
|
7b51b8db72 | ||
|
|
fddb08554d | ||
|
|
14116c24b8 | ||
|
|
9307cf6259 | ||
|
|
39de752084 | ||
|
|
d50783bb7f | ||
|
|
2f22563d8d | ||
|
|
a0c7c134d3 | ||
|
|
e8d08572c6 | ||
|
|
0191bde3e6 | ||
|
|
5c738d8f4d | ||
|
|
6ca8817108 | ||
|
|
b9f5c0b40e | ||
|
|
c89cfec0c8 | ||
|
|
85840a9fa6 | ||
|
|
a9ff99d48e | ||
|
|
160fdaef88 | ||
|
|
c020a739c4 | ||
|
|
3b6e34fed8 | ||
|
|
e4d09f118d | ||
|
|
662adb7bda | ||
|
|
9c479f4462 | ||
|
|
447da26e16 | ||
|
|
9878e59a1b | ||
|
|
af0530c764 | ||
|
|
30067567ab | ||
|
|
501509f4df | ||
|
|
b0edfdc976 | ||
|
|
4745ed2242 | ||
|
|
4112828108 | ||
|
|
17e5edc17d | ||
|
|
24a0f6f6c4 | ||
|
|
76975298f0 | ||
|
|
770ae6d5cf | ||
|
|
25fdb28540 | ||
|
|
6a026e0039 | ||
|
|
edb8cd0ba7 | ||
|
|
0908fcab89 | ||
|
|
ceb18f613f | ||
|
|
72776eee35 | ||
|
|
0cf67aa8bb | ||
|
|
1893aef144 | ||
|
|
d2806e7fe0 | ||
|
|
174e4be581 | ||
|
|
583b47bf2f | ||
|
|
b623363369 | ||
|
|
2b72adbfed | ||
|
|
2b1f1a514d | ||
|
|
af452c014d | ||
|
|
53cfa8deee | ||
|
|
adefb7de07 | ||
|
|
d17ba78413 | ||
|
|
56419385c3 | ||
|
|
4b55018014 | ||
|
|
449b4157c3 | ||
|
|
cad0113d59 | ||
|
|
4e98fd7839 | ||
|
|
366eb9d0dd | ||
|
|
ed6cb9e00d | ||
|
|
9267c05a9b | ||
|
|
e2d574eb5d | ||
|
|
658fe92f9e | ||
|
|
1525572c03 | ||
|
|
90b548973b | ||
|
|
fa188868b1 | ||
|
|
719ee3456a | ||
|
|
afc136d4f9 | ||
|
|
802ceb1ff5 | ||
|
|
adf9aac96a | ||
|
|
1898ff0813 | ||
|
|
e97ada9654 | ||
|
|
1f79a454c4 | ||
|
|
029493f3ed | ||
|
|
882332fc55 | ||
|
|
a318765143 | ||
|
|
bafed33c1f | ||
|
|
43451bdaff | ||
|
|
a2c9b59a1e | ||
|
|
164cb11cf3 | ||
|
|
84fab1da37 | ||
|
|
9843fb0144 | ||
|
|
8b23750641 | ||
|
|
3d775da19f | ||
|
|
ec0880ade3 | ||
|
|
e3cfb240d0 |
8
.editorconfig
Normal file
@@ -0,0 +1,8 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
4
.gitignore
vendored
@@ -3,7 +3,7 @@ node_modules
|
||||
|
||||
# Build directories
|
||||
src/public/dist/local/bundle/
|
||||
src/public/dist/standalone/bundle/
|
||||
build/
|
||||
|
||||
# example for dev
|
||||
# example-project
|
||||
@@ -12,4 +12,4 @@ src/public/dist/standalone/bundle/
|
||||
.idea
|
||||
.DS_STORE
|
||||
|
||||
yarn.lock
|
||||
yarn.lock
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
.idea
|
||||
example-project
|
||||
docs
|
||||
docs
|
||||
src/public/js
|
||||
build
|
||||
|
||||
11
Dockerfile
Normal file
@@ -0,0 +1,11 @@
|
||||
FROM node:14-slim
|
||||
|
||||
WORKDIR /usr/src/codecrumbs
|
||||
|
||||
COPY package*.json ./
|
||||
|
||||
RUN yarn install
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 2018 3018
|
||||
126
README.md
@@ -18,94 +18,108 @@
|
||||
<a href="#support">Support</a>
|
||||
</h3>
|
||||
|
||||
## What
|
||||
> **Have you ever got lost in a big or unknown codebase?** This tool will help you to solve that. Also, it will increase your development speed and give more knowledge about your application architecture.
|
||||
>
|
||||
>**How it works?** You run `codecrumbs` command for a codebase, it analyzes source code and builds its visual representation. Write down a codecrumb-comment and codebase state will be reflected by visual client in browser on the fly.
|
||||
>
|
||||
>-[@bliashenko](https://twitter.com/bliashenko)
|
||||
**Have you ever got lost in a big or unknown codebase?** This tool will help you to solve that. Also, it will increase your development speed and give more knowledge about your application architecture.
|
||||
> If you like this project, follow me on Twitter [@bliashenko](https://twitter.com/bliashenko) to hear about things I am building.
|
||||
|
||||
## Codecrumbs v2
|
||||
Check out new version of this project as [standalone application](https://codecrumbs.io). Just in a few clicks you can start exploring a codebase in more efficient way, create interactive visual guides and share them with others on your own blog! See [quick guide here](https://codecrumbs.io/guides/web-app-with-github/).
|
||||
|
||||
<p align="center">
|
||||
<a href="https://codecrumbs.io" target="_blank">
|
||||
<img src="https://codecrumbs.io/external/img/common/app-ui-1.png" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
|
||||
## Demo
|
||||
Check out the example of [**standalone version running here**](https://codecrumbs.io/#showcase=todo-react-redux).
|
||||
|
||||
<img src="/docs/main-ui-2.png" width="100%"/>
|
||||
|
||||
Check out prepared example for [**standalone version running here**](https://codecrumbs.io/app).
|
||||
|
||||
## Codecrumbs v1
|
||||
|
||||
>**How it works?** You run `codecrumbs` command for a codebase, it analyzes source code and builds its visual representation. Write down a codecrumb-comment and codebase state will be reflected by visual client in browser on the fly.
|
||||
>
|
||||
> Check out [my talk at React-Finland](https://www.youtube.com/watch?v=S_1-1jzLxm4) for more details.
|
||||
|
||||
|
||||
<img src="/docs/main-ui-3.png" width="100%"/>
|
||||
|
||||
## Get started
|
||||
### Install and run
|
||||
>Pre-condition: update/install `NodeJS` version to be >= *8.11.1*
|
||||
|
||||
>Pre-condition: update/install `NodeJS` version to be >= *8.11.1*
|
||||
|
||||
1) Install ```codecrumbs``` globally (```yarn global add codecrumbs```)
|
||||
2) Run ```codecrumbs -d project-src-dir -e project-src-dir/index.js```. Change parameters to match your project:```-d``` is *directory with source code*, ```-e``` is *entry point file* .
|
||||
3) Go to [http://localhost:2018](http://localhost:2018/#) in the browser to check it out.
|
||||
|
||||
### CLI
|
||||
Parameter | Description | Example
|
||||
--- | --- | ---
|
||||
```-d```, ```--dir``` | Relative path to project source code directory | ```-d src```
|
||||
```-e```, ```--entry``` | Relative path to project source entry point file (must be inside ```dir```) | ```-e src/app.js```
|
||||
```-x```, ```--excludeDir``` | Relative path(or paths separated by ```,```) to directories for exclusion | ```-x src/doc,src/thirdparty```
|
||||
```-p```, ```--port``` | Port for Codecrumbs client (optional, default *2018*) | ```-p 2019```
|
||||
```-n```, ```--projectName``` | Project name alias (optional, default same as ```-d``` value) | ```-n my-hello-world```
|
||||
### Configuration
|
||||
Run codecrumbs with CLI params or specify static config file `codecrumbs.config.js` (see example [here](/example-project/codecrumbs.config.js))
|
||||
|
||||
CLI | Config file | Description | Example
|
||||
--- | --- | --- | ---
|
||||
```d``` | ```projectDir``` | Relative path to project source code directory | ```-d src```
|
||||
```e``` | ```entryPoint``` | Relative path to project source entry point file (must be inside ```dir```) | ```-e src/app.js```
|
||||
```x``` | ```excludeDir``` | Relative path(or paths separated by ```,```) to directories for exclusion | ```-x src/doc,src/thirdparty```
|
||||
```p``` | ```clientPort``` | Port for Codecrumbs client (optional, default *2018*) | ```-p 2019```
|
||||
```n``` | ```projectNameAlias``` | Project name alias (optional, default same as ```-d``` value) | ```-n my-hello-world```
|
||||
```C``` | - | Path to codecrumbs.config.js (optional, by default will try to find the file in PWD) | ```-C config/codecrumbs.config.js```
|
||||
```D``` | ```debugModeEnabled``` | Enable debug mode for logs (optional, default is ```false```) | ```-D```
|
||||
|
||||
## Features
|
||||
### Breadcrumbs and trails
|
||||
|
||||
<img src="/docs/cc-ui-2.png" width="750"/>
|
||||
<img src="/docs/cc-ui-3.png" width="750"/>
|
||||
|
||||
UI explained:
|
||||
- enable "Codecrumbs" switch to have codecrumbs tree on the scheme (drop-down contains extra configuration)
|
||||
- choose "current" codecrumbs trail to display (can be either trail or all other "simple" codecrumbs)
|
||||
- select connection between two steps (code for two codecrumbs will be opened in "Sidebar" under "Crumbs" tab)
|
||||
- set other options in dropdowns to configure behaviour of the diagram
|
||||
- set other options in dropdowns to configure behaviour of the diagram (show code blocks, details, etc.)
|
||||
|
||||
**How to get there?**
|
||||
**How to get there?**
|
||||
|
||||
Leave breadcrumb in code by writing down a comment: ```//cc:[parameters;]```.
|
||||
|
||||
```cc``` (stands for "CodeCrumb") is a prefix which used by the parser; check example of parameters in the table below:
|
||||
|
||||
```cc``` (stands for "CodeCrumb") is a prefix which used by the parser; check example of parameters in the table below:
|
||||
|
||||
Example | Description | Use case
|
||||
--- | --- | ---
|
||||
```//cc:remember place``` | simple breadcrumb, ```remember place``` is a title of our first breadcrumb | Mark an important place to not forget where it was
|
||||
```//cc:here is bug;well, seems like a bug in logic``` | simple breadcrumb, ```well, seems like a bug in logic``` is details for breadcrumb, separated by ```;``` | Add extra information, will be rendered in popups
|
||||
```//cc:signin#3;enable route``` | trail of breadcrumbs,```signin``` is the **trail ID**, ```#3``` is order **number of step**, ```enable route``` is a title describing the step. | A sequence of codecrumbs, use to describe some data flow (e.g. user login, or form submit, etc.).
|
||||
```//cc:signin#1;firebase sign in;+2;do call to firebase with credentials``` | trail of breadcrumbs,```+2``` is number of lines to highlight, separated by ```;``` | Use number of lines to highlight the code related to breadcrumb
|
||||
```//cc:signin#1;firebase sign in;+2;do call to firebase with credentials``` | trail of breadcrumbs,```+2``` is number of lines to highlight, separated by ```;``` | Use number of lines to highlight the code related to breadcrumb
|
||||
|
||||
> Note: current version supports single line comments only.
|
||||
> Note: current version supports single line comments only.
|
||||
|
||||
> Hint: you can use trail id without step number (e.g. ```//cc:groupname#;test```) just to group breadcrumbs, you always can add step numbers later when you know the correct order.
|
||||
|
||||
### Multi-codebase integration
|
||||
You might be interested to study connections between several codebases (sub-modules), codecrumbs supports that.
|
||||
Simply start codecrumbs multiple times (once for each codebase), it all **will be synced in one picture** inside the browser tab. To control a diagram UI - select it by clicking on it.
|
||||
|
||||
E.g. for client-server application, go to the source directory for your server code and run `codecrumbs -e your-server-src/index.py -d your-server-src`, same for client `codecrumbs -e src-client/index.js -d src-client`.
|
||||
> **Note:** codebases can be located wherever you want (**no** need to have them like mono-repo, etc.), simply run `codecrumbs` for directory you need.
|
||||
E.g. for client-server application, go to the source directory for your server code and run `codecrumbs -e your-server-src/index.py -d your-server-src`, same for client `codecrumbs -e src-client/index.js -d src-client`.
|
||||
> **Note:** codebases can be located wherever you want (**no** need to have them like mono-repo, etc.), simply run `codecrumbs` for directory you need.
|
||||
|
||||
<img src="/docs/multi-codebase-cc.png" width="100%"/>
|
||||
<img src="/docs/multi-codebase-cc-2.png" width="100%"/>
|
||||
|
||||
### Multi-language support
|
||||
Current version supports next programming languages:
|
||||
Current version supports next programming languages:
|
||||
- `C#`
|
||||
- `C++`
|
||||
- `Fortran`
|
||||
- `Go`
|
||||
- `Haskell`
|
||||
- `Java`
|
||||
- `JavaScript`
|
||||
- `TypeScript`
|
||||
- `Kotlin`
|
||||
- `PHP`
|
||||
- `Python`
|
||||
- `Ruby`
|
||||
- `PHP`
|
||||
- `Java`
|
||||
- `Kotlin`
|
||||
- `C++`
|
||||
- `C#`
|
||||
- `Fortran`
|
||||
- `Haskell`
|
||||
- `TypeScript`
|
||||
|
||||
Please file an issue to support other language you would like to have.
|
||||
|
||||
### Download & Upload (learn and share your knowledge)
|
||||
|
||||
You can take a snapshot of application state at any point of time and share it with others. Simply download the json file of codecrumbs store (*top-right corner, "setup -> download"*). This json file can be then uploaded to codecrumbs (*top-right corner, "setup -> upload"*) to represent exactly same picture, even without having that project locally!
|
||||
|
||||
<img src="/docs/upload-feature-2.gif" width="100%"/>
|
||||
|
||||
### Dependencies
|
||||
> Note: In current version only [JavaScript, TypeScript] offer this feature
|
||||
> Note: In current version only [JavaScript, TypeScript] offer this feature
|
||||
|
||||
<img src="/docs/dep-ui-2.png" width="100%"/>
|
||||
|
||||
@@ -115,17 +129,12 @@ UI explained:
|
||||
- select connection between modules (all involved files will be opened in "Sidebar", so you can see “what is imported” and “its implementation”)
|
||||
|
||||
### Flowchart
|
||||
> Note: In current version only JavaScript offers this feature
|
||||
> Note: In current version only JavaScript offers this feature
|
||||
|
||||
<img src="/docs/flow-ui.png" width="100%"/>
|
||||
|
||||
[js2flowchart](https://github.com/Bogdan-Lyashenko/js-code-to-svg-flowchart) is used in the sidebar to draw flowchart for the selected file code.
|
||||
|
||||
## Case studies
|
||||
The tool (codecrumbs) allows us to learn, document and explain a codebase much faster. Also, with *Download & Upload* feature it becomes super easy to collect and share your "investigation results".
|
||||
|
||||
The ultimate goal is to have many case studies hosting at [https://codecrumbs.io](https://codecrumbs.io/). **The library of projects "explained with codecrumbs", the place for collaborative learning**. More features around that coming soon, stay tuned.
|
||||
|
||||
## Support
|
||||
Any support is very much appreciated! 👍 😘 ❤️
|
||||
If you like this project, please, **put a :star: and tweet about it**. Thanks!
|
||||
@@ -134,7 +143,14 @@ Please, consider [making financial donation](https://opencollective.com/codecrum
|
||||
|
||||
<a href="https://opencollective.com/codecrumbs/donate" target="_blank">
|
||||
<img src="https://opencollective.com/codecrumbs/donate/button@2x.png?color=blue" width=300 />
|
||||
</a>
|
||||
</a>
|
||||
|
||||
#### Sponsors
|
||||
Development supported by [0+X](https://0x.se)
|
||||
|
||||
<a href="https://0x.se" target="_blank">
|
||||
<img src="https://avatars0.githubusercontent.com/u/16350669?s=200&v=4" width=100 />
|
||||
</a>
|
||||
|
||||
#### Backers
|
||||
<a href="https://opencollective.com/codecrumbs/backer/0/website" target="_blank"><img src="https://opencollective.com/codecrumbs/backer/0/avatar.svg"></a>
|
||||
@@ -150,6 +166,4 @@ yarn && yarn start
|
||||
|
||||
## WIP
|
||||
Next features are developing:
|
||||
- **eject codecrumbs** - ability to remove all "breadcrumbs" from source code in "one click"
|
||||
- **data transferring between cc trail steps**
|
||||
- **VS Code extension** - some neat features right inside the code editor. Checkout [the repo here](https://github.com/Bogdan-Lyashenko/vs-code-codecrumbs).
|
||||
- **VS Code extension** - some neat features right inside the code editor. Checkout [the repo here](https://github.com/Bogdan-Lyashenko/vs-code-codecrumbs).
|
||||
|
||||
52
cli/index.cli.js
Normal file → Executable file
@@ -1,43 +1,57 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const path = require('path');
|
||||
const program = require('commander');
|
||||
const colors = require('colors');
|
||||
const _ = require('lodash');
|
||||
|
||||
const showUpdatesInfo = require('./updatesInfo');
|
||||
const server = require('../src/server');
|
||||
|
||||
showUpdatesInfo();
|
||||
|
||||
program
|
||||
.option('-e, --entry [entryFile]', 'Specify path to entry point file. E.g. `src/app.js`')
|
||||
.option(
|
||||
'-d, --dir [projectDir]',
|
||||
'Specify path to project source code directory. E.g. `src`',
|
||||
''
|
||||
)
|
||||
.option('-e, --entry [entryPoint]', 'Specify path to entry point file. E.g. `src/app.js`')
|
||||
.option('-d, --dir [projectDir]', 'Specify path to project source code directory. E.g. `src`', '')
|
||||
.option(
|
||||
'-w, --webpack [webpackConfigFile]',
|
||||
'Specify path to webpack config file. E.g. webpack.config.js'
|
||||
)
|
||||
.option(
|
||||
'-t, --tsconfig [tsConfigFile]',
|
||||
'Specify path to typeScript config file. E.g. tsConfig.json'
|
||||
)
|
||||
.option('-p, --port [defaultPort]', 'Specify port for Codecrumbs client. E.g. 3333', 2018)
|
||||
.option('-i, --ideCmd [ideCmd]', 'IDE command to open file')
|
||||
.option('-x, --excludeDir [excludeDirectories]', 'Exclude directories')
|
||||
.option('-n, --projectName [projectNameAlias]', 'Project name alias')
|
||||
.option('-C, --configFile [pathToConfigFile]', 'Path to codecrumbs.config.js')
|
||||
.option('-D, --debugModeEnabled [debugModeEnabled]', 'Enable debug mode for logs.')
|
||||
.parse(process.argv);
|
||||
|
||||
if (!program.entry || !program.dir) {
|
||||
const pathToConfigFile = program.configFile || 'codecrumbs.config.js';
|
||||
const configFileExists = server.checkIfPathExists(pathToConfigFile);
|
||||
if ((!program.entry || !program.dir) && !configFileExists) {
|
||||
console.log(
|
||||
colors.magenta(
|
||||
'Please specify `entry` and `dir` params. E.g. `codecrumbs -e src/app.js -d src`'
|
||||
'Please specify `entryPoint` and `projectDir` params (e.g. `codecrumbs -e src/app.js -d src`). Or use `-C codecrumbs.config.js` instead.'
|
||||
)
|
||||
);
|
||||
process.exit();
|
||||
}
|
||||
|
||||
server.setup(
|
||||
{
|
||||
projectNameAlias: program.projectName,
|
||||
entryPoint: program.entry,
|
||||
projectDir: program.dir,
|
||||
webpackConfigPath: program.webpack,
|
||||
clientPort: program.port,
|
||||
excludeDir: program.excludeDir
|
||||
},
|
||||
false
|
||||
);
|
||||
const configFromFile = configFileExists ? require(path.resolve(pathToConfigFile)) : {};
|
||||
|
||||
const configFromCLI = {
|
||||
projectNameAlias: program.projectName,
|
||||
entryPoint: program.entry,
|
||||
projectDir: program.dir,
|
||||
webpackConfigPath: program.webpack,
|
||||
tsConfigPath: program.tsconfig,
|
||||
clientPort: program.port,
|
||||
excludeDir: program.excludeDir,
|
||||
ideCmd: program.ideCmd,
|
||||
debugModeEnabled: program.debugModeEnabled
|
||||
};
|
||||
|
||||
server.setup(_.merge(configFromCLI, configFromFile), { isDev: false });
|
||||
|
||||
20
cli/updatesInfo.js
Normal file
@@ -0,0 +1,20 @@
|
||||
const colors = require('colors');
|
||||
const exec = require('child_process').exec;
|
||||
|
||||
module.exports = () => {
|
||||
try {
|
||||
exec('npm outdated codecrumbs').stdout.on('data', function(data) {
|
||||
const list = data
|
||||
.split(' ')
|
||||
.filter(v => !!v)
|
||||
.map(v => v.trim());
|
||||
|
||||
const latestVersion = list[list.length - 2];
|
||||
console.log(
|
||||
colors.cyan.underline(
|
||||
`There is new version of codecrumbs (${latestVersion}) available! Please update to have all latest features and improvements!`
|
||||
)
|
||||
);
|
||||
});
|
||||
} catch (e) {}
|
||||
};
|
||||
BIN
docs/cc-ui-2.png
|
Before Width: | Height: | Size: 66 KiB |
BIN
docs/cc-ui-3.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
docs/ide-integration.gif
Normal file
|
After Width: | Height: | Size: 5.1 MiB |
|
Before Width: | Height: | Size: 165 KiB |
BIN
docs/main-ui-3.png
Normal file
|
After Width: | Height: | Size: 236 KiB |
BIN
docs/multi-codebase-cc-2.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 1.8 MiB |
7
example-project/codecrumbs.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
entryPoint: 'example-project/src-client/index.js',
|
||||
projectDir: 'example-project/src-client',
|
||||
clientPort: 1234,
|
||||
projectNameAlias: 'example-project-for-client',
|
||||
debugModeEnabled: true
|
||||
};
|
||||
@@ -1,7 +1,7 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
// cc:main function
|
||||
//cc:main function
|
||||
int main()
|
||||
{
|
||||
cout << "Hello, World!";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// cc:main function
|
||||
//cc:main function
|
||||
using System;
|
||||
namespace HelloWorld
|
||||
{
|
||||
|
||||
7
example-project/languages/go-lang.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package main
|
||||
import "fmt"
|
||||
|
||||
// cc:main function
|
||||
func main() {
|
||||
fmt.Println("hello world")
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
public class HelloWorld {
|
||||
|
||||
// cc: main function
|
||||
//cc: main function
|
||||
public static void main(String[] args) {
|
||||
// Prints "Hello, World" to the terminal window.
|
||||
System.out.println("Hello, World");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// cc:main function
|
||||
//cc:main function
|
||||
function greeting() {
|
||||
console.log('Hello world!');
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// cc:main function
|
||||
//cc:main function
|
||||
|
||||
fun main(args : Array<String>) {
|
||||
println("Hello, World!")
|
||||
|
||||
2
example-project/languages/lua-lang.lua
Normal file
@@ -0,0 +1,2 @@
|
||||
-- hello world program
|
||||
print ("Hello World!")
|
||||
2
example-project/languages/ocaml.ml
Normal file
@@ -0,0 +1,2 @@
|
||||
/* cc:main function */
|
||||
let hello = () => "Hello, World!";
|
||||
7
example-project/languages/perl-lang.pl
Normal file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# cc: main function.
|
||||
print "Hello, World!\n";
|
||||
@@ -1,5 +1,5 @@
|
||||
<?php
|
||||
// cc:main function
|
||||
//cc:main function
|
||||
echo "Hello World!";
|
||||
echo "PHP is so easy!";
|
||||
?>
|
||||
@@ -1,3 +1,3 @@
|
||||
# cc:main function
|
||||
|
||||
puts 'Hello, world!'
|
||||
puts 'Hello, world!'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// cc:main function
|
||||
//cc:main function
|
||||
function greeting() {
|
||||
console.log('Hello world!');
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
|
||||
function authenticate(provider) {
|
||||
return dispatch => {
|
||||
//cc:signin#1;firebase sign in;+2;call to firebase with auth provider, proceed if success response
|
||||
//cc:signin#1;firebase sign in;+1;call to firebase with auth provider, proceed if success response
|
||||
firebaseAuth.signInWithPopup(provider)
|
||||
.then(result => dispatch(signInSuccess(result)))
|
||||
.catch(error => dispatch(signInError(error)));
|
||||
|
||||
@@ -13,7 +13,7 @@ export function authReducer(state = new AuthState(), {payload, type}) {
|
||||
case INIT_AUTH:
|
||||
case SIGN_IN_SUCCESS:
|
||||
return state.merge({
|
||||
authenticated: !!payload, // cc:signin#5;toggle 'authenticated' flag
|
||||
authenticated: !!payload, //cc:signin#5;toggle 'authenticated' flag
|
||||
id: payload ? payload.uid : null
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//cc:firebase config
|
||||
//cc:firebase config;and some details
|
||||
export const firebaseConfig = {
|
||||
apiKey: 'AIzaSyBsVVpEDrlNPEmshLcmOuE0FxhjPn0AqMg',
|
||||
authDomain: 'todo-react-redux.firebaseapp.com',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import createHistory from 'history/createBrowserHistory';
|
||||
|
||||
|
||||
export default createHistory();
|
||||
export default createHistory();
|
||||
22
example-project/src-client/test_tml.vue
Normal file
@@ -0,0 +1,22 @@
|
||||
|
||||
<template>
|
||||
<p>{{ greeting }} World!</p>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
module.exports = {
|
||||
data: function () {
|
||||
return {
|
||||
greeting: 'Hello'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
//cc:test vue
|
||||
<style scoped>
|
||||
p {
|
||||
font-size: 2em;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -10,7 +10,7 @@ import RequireUnauthRoute from '../components/require-unauth-route';
|
||||
import SignInPage from '../pages/sign-in';
|
||||
import TasksPage from '../pages/tasks';
|
||||
|
||||
//cc:layout#1;describe pages
|
||||
//cc:layout#1;describe pages;some details long description for separare popup
|
||||
const App = ({authenticated, signOut}) => (
|
||||
<div>
|
||||
<Header
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Route, Redirect } from 'react-router-dom'
|
||||
|
||||
//cc:signin#6;enable route;+6
|
||||
//cc:signin#6;enable route;details
|
||||
const RequireAuthRoute = ({component: Component, authenticated, ...rest}) => (
|
||||
<Route
|
||||
{...rest}
|
||||
|
||||
@@ -6,7 +6,7 @@ import Icon from '../icon';
|
||||
|
||||
import './task-item.css';
|
||||
|
||||
//cc:there is task
|
||||
//cc:there is task;extra
|
||||
export class TaskItem extends Component {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
|
||||
@@ -37,7 +37,7 @@ const mapDispatchToProps = {
|
||||
signInWithGoogle: authActions.signInWithGoogle,
|
||||
signInWithTwitter: authActions.signInWithTwitter
|
||||
};
|
||||
|
||||
//cc:signin#7;test
|
||||
export default withRouter(
|
||||
connect(
|
||||
null,
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\CommentRequest;
|
||||
|
||||
use App\Models\Post;
|
||||
use App\Models\Comment;
|
||||
use Auth;
|
||||
use Validator;
|
||||
|
||||
class CommentController extends Controller
|
||||
{
|
||||
function index()
|
||||
{
|
||||
// index
|
||||
}
|
||||
}
|
||||
18
example-project/src-php/Http/Controllers/PostController.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Http\Requests\PostRequest;
|
||||
use App\Models\Post;
|
||||
use App\Models\Category;
|
||||
use Hashids\Hashids;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class PostController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
// index
|
||||
}
|
||||
}
|
||||
15
example-project/src-php/Http/Requests/PostRequest.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Requests;
|
||||
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use App\Rules\Category;
|
||||
|
||||
|
||||
class PostRequest extends FormRequest
|
||||
{
|
||||
public function authorize()
|
||||
{
|
||||
// authorize
|
||||
}
|
||||
}
|
||||
13
example-project/src-php/Models/Category.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Category extends Model
|
||||
{
|
||||
public function posts()
|
||||
{
|
||||
// posts
|
||||
}
|
||||
}
|
||||
13
example-project/src-php/Models/Post.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Post extends Model
|
||||
{
|
||||
public function user()
|
||||
{
|
||||
// user
|
||||
}
|
||||
}
|
||||
7
example-project/src-php/index.php
Normal file
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use App\Http\Controllers\CommentController;
|
||||
use App\Http\Controllers\PostController;
|
||||
use App\Http\Requests\PostRequest;
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
import { RouteComponentProps } from 'react-router-dom';
|
||||
import { Card, CardHeader, CardContent } from '@material-ui/core';
|
||||
import { LoginForm } from './loginForm';
|
||||
import { LoginForm } from '@src/components/login/loginForm';
|
||||
import { isValidLogin } from '../../api/login';
|
||||
import { LoginEntity, createEmptyLogin } from '../../model';
|
||||
import { NotificationComponent } from '../../common/components/notification';
|
||||
|
||||
9
example-project/src-typescript/tsConfig.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": "example-project",
|
||||
"moduleResolution": "node",
|
||||
"paths": {
|
||||
"@src/*": ["src-typescript/*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
29
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "codecrumbs",
|
||||
"version": "1.2.14",
|
||||
"version": "1.8.3",
|
||||
"author": "Bohdan Liashenko",
|
||||
"license": "BSD-3-Clause",
|
||||
"repository": {
|
||||
@@ -13,9 +13,11 @@
|
||||
"server:two": "node src/index.dev.js two",
|
||||
"client-dev": "cd src/public && webpack --config webpack.dev.js --progress --colors --watch --env dev",
|
||||
"server-dev": "nodemon src/index.dev.js",
|
||||
"server:cli": "node cli/index.cli.js -e example-project/src-client/index.js -d example-project/src-client/",
|
||||
"server-debug": "nodemon --inspect src/index.dev.js",
|
||||
"build": "cd src/public && webpack --config webpack.prod.js --progress --colors",
|
||||
"start:standalone": "cd src/public/dist/standalone && http-server",
|
||||
"clean": "rm -rf build",
|
||||
"webpack-compile-local": "cd src/public && webpack --config webpack.local.js --progress",
|
||||
"build": "yarn clean && yarn webpack-compile-local",
|
||||
"pretty": "prettier --write \"./src/public/js/**/*.js\""
|
||||
},
|
||||
"bin": {
|
||||
@@ -23,7 +25,6 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.1.2",
|
||||
"@babel/polyfill": "^7.0.0",
|
||||
"@babel/traverse": "^7.1.0",
|
||||
"antd": "^3.9.2",
|
||||
"chalk": "^2.4.2",
|
||||
@@ -34,15 +35,15 @@
|
||||
"d3-flextree": "^2.1.1",
|
||||
"directory-tree": "^2.1.0",
|
||||
"file-saver": "^2.0.0",
|
||||
"http-server": "^0.11.1",
|
||||
"js2flowchart": "^1.1.7",
|
||||
"http-server": "0.9.0",
|
||||
"js2flowchart": "1.3.2",
|
||||
"lodash": "^4.17.10",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"madge": "^3.3.0",
|
||||
"madge": "^3.4.4",
|
||||
"php-parser": "^3.0.2",
|
||||
"portscanner": "^2.2.0",
|
||||
"react": "^16.7.0",
|
||||
"react-dom": "^16.7.0",
|
||||
"react-draggable": "^3.0.5",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-redux": "^5.0.7",
|
||||
"react-syntax-highlighter": "8.0.1",
|
||||
"redux": "^4.0.0",
|
||||
@@ -54,20 +55,24 @@
|
||||
"websocket": "1.0.27"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.4.4",
|
||||
"@babel/core": "^7.1.2",
|
||||
"@babel/plugin-proposal-class-properties": "^7.5.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/plugin-transform-runtime": "^7.4.4",
|
||||
"@babel/preset-env": "^7.1.0",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@commitlint/cli": "^7.3.2",
|
||||
"@commitlint/config-conventional": "^7.3.1",
|
||||
"babel-loader": "^8.0.4",
|
||||
"babel-plugin-import": "^1.9.1",
|
||||
"babel-plugin-transform-define": "^1.3.1",
|
||||
"css-loader": "^0.28.11",
|
||||
"husky": "^1.3.1",
|
||||
"node-sass": "^4.9.3",
|
||||
"less": "^3.9.0",
|
||||
"less-loader": "^5.0.0",
|
||||
"nodemon": "^1.18.7",
|
||||
"prettier": "^1.14.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"style-loader": "^0.21.0",
|
||||
"webpack": "^4.20.2",
|
||||
"webpack-bundle-analyzer": "^3.0.3",
|
||||
|
||||
@@ -5,7 +5,8 @@ const namespaceOne = {
|
||||
projectDir: `example-project/src-client`,
|
||||
entryPoint: `example-project/src-client/index.js`,
|
||||
webpackConfigPath: `example-project/webpack.config.js`,
|
||||
clientPort: 2018
|
||||
clientPort: 2018,
|
||||
debugModeEnabled: true
|
||||
};
|
||||
|
||||
const namespaceTwo = {
|
||||
@@ -16,11 +17,19 @@ const namespaceTwo = {
|
||||
};
|
||||
|
||||
const namespaceTypeScriptExample = {
|
||||
projectNameAlias: 'ts-example-server',
|
||||
projectDir: `example-project/src-typescript`,
|
||||
entryPoint: `example-project/src-typescript/index.tsx`,
|
||||
clientPort: 2018
|
||||
};
|
||||
projectNameAlias: 'ts-example-server',
|
||||
projectDir: `example-project/src-typescript`,
|
||||
entryPoint: `example-project/src-typescript/index.tsx`,
|
||||
tsConfigPath: `example-project/src-typescript/tsConfig.json`,
|
||||
clientPort: 2018
|
||||
};
|
||||
|
||||
const namespacePhpExample = {
|
||||
projectNameAlias: 'php-example-server',
|
||||
projectDir: `example-project/src-php`,
|
||||
entryPoint: `example-project/src-php/index.php`,
|
||||
clientPort: 2018
|
||||
};
|
||||
|
||||
const namespaceDebug = {
|
||||
projectNameAlias: 'debug',
|
||||
@@ -38,9 +47,9 @@ const namespaceLanguageTest = {
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const namespaces = {
|
||||
two: namespaceTwo,
|
||||
ts: namespaceTypeScriptExample
|
||||
two: namespaceTwo,
|
||||
ts: namespaceTypeScriptExample,
|
||||
php: namespacePhpExample
|
||||
};
|
||||
const namespace = namespaces[args[0]] !== undefined ? namespaces[args[0]] : namespaceOne;
|
||||
const isDev = true;
|
||||
server.setup(namespace, isDev);
|
||||
server.setup(namespace, { isDev: true });
|
||||
|
||||
36
src/public/babel.config.js
Normal file
@@ -0,0 +1,36 @@
|
||||
const packageJson = require('../../package');
|
||||
|
||||
module.exports = function(app) {
|
||||
app.cache(true);
|
||||
|
||||
const presets = [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
targets: {
|
||||
browsers: ['last 2 versions']
|
||||
},
|
||||
modules: false
|
||||
}
|
||||
],
|
||||
'@babel/preset-react'
|
||||
];
|
||||
|
||||
const plugins = [
|
||||
['import', { libraryName: 'antd', libraryDirectory: 'es', style: 'css' }],
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'@babel/plugin-transform-runtime',
|
||||
'@babel/plugin-proposal-class-properties',
|
||||
[
|
||||
'transform-define',
|
||||
{
|
||||
'process.env.CODECRUMBS_VERSION': packageJson.version
|
||||
}
|
||||
]
|
||||
];
|
||||
|
||||
return {
|
||||
presets,
|
||||
plugins
|
||||
};
|
||||
};
|
||||
BIN
src/public/dist/standalone/Menlo-Regular.ttf
vendored
BIN
src/public/dist/standalone/favicon.ico
vendored
|
Before Width: | Height: | Size: 1.1 KiB |
52
src/public/dist/standalone/index.html
vendored
@@ -1,52 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Codecrumbs standalone: learn and share your code knowledge!</title>
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: menlo-regular;
|
||||
src: url('Menlo-Regular.ttf');
|
||||
}
|
||||
|
||||
svg { font-family: menlo-regular, monospace; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="mount-node" style="height: 100%">
|
||||
<div id="placeholder" style="text-align: center; color: #1890ff">
|
||||
Loading standalone codecrumbs experience...
|
||||
</div>
|
||||
</div>
|
||||
<script src="./bundle/main.bundle.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
(function(window) {
|
||||
if (!window.codecrumbs) {
|
||||
console.error('Codecrumbs project is not loaded!');
|
||||
return false;
|
||||
}
|
||||
|
||||
var hash = location.hash;
|
||||
var key = '#showcase=';
|
||||
var showCaseName = hash.slice(hash.indexOf(key) + key.length) || 'todo-react-redux';
|
||||
|
||||
var fileElement = document.createElement('div');
|
||||
fileElement.innerText = 'Fetching "' + showCaseName + '" showcase...';
|
||||
document.getElementById('placeholder').appendChild(fileElement);
|
||||
|
||||
window.fetch('./json/' + showCaseName + '.json')
|
||||
.then(function(response) {
|
||||
return response.json();
|
||||
}).then((object) => {
|
||||
window.codecrumbs.default({ standalone: true, predefinedState: object.data }, 'mount-node');
|
||||
}).catch((e) => {
|
||||
console.error(e);
|
||||
|
||||
document.getElementById('placeholder').innerText = 'Ooopps.. :( Failed to load. ' +
|
||||
'Set hash params and reload page. E.g. #showcase=todo-react-redux'
|
||||
});
|
||||
})(window)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
3804
src/public/dist/standalone/json/todo-react-redux.json
vendored
@@ -1,27 +1,30 @@
|
||||
import React, { Suspense } from 'react';
|
||||
import Spin from 'antd/lib/spin';
|
||||
import 'antd/lib/spin/style/css';
|
||||
|
||||
import { isMobile } from 'utils/index';
|
||||
import Spin from 'antd/es/spin';
|
||||
import 'antd/es/spin/style';
|
||||
|
||||
const DataBus = React.lazy(() => import(/* webpackChunkName: "data-bus" */ 'core/dataBus'));
|
||||
import { isMobile } from './utils/index';
|
||||
|
||||
const DataBus = React.lazy(() => import(/* webpackChunkName: "data-bus" */ './core/dataBus'));
|
||||
const ViewsSwitches = React.lazy(() =>
|
||||
import(/* webpackChunkName: "view-switches" */ 'components/topBar/controls/ViewSwitches/ViewSwitchesContainer')
|
||||
import(/* webpackChunkName: "view-switches" */ './components/topBar/controls/ViewSwitches/ViewSwitchesContainer')
|
||||
);
|
||||
const TopBar = React.lazy(() =>
|
||||
import(/* webpackChunkName: "top-bar" */ 'components/topBar/subPanel/SubPanelContainer')
|
||||
import(/* webpackChunkName: "top-bar" */ './components/topBar/subPanel/SubPanelContainer')
|
||||
);
|
||||
const TreeDiagramsContainer = React.lazy(() =>
|
||||
import(/* webpackChunkName: "tree-diagram" */ 'components/treeDiagram/TreeDiagramsContainer')
|
||||
import(/* webpackChunkName: "tree-diagram" */ './components/treeDiagram/TreeDiagramsContainer')
|
||||
);
|
||||
const SideBar = React.lazy(() =>
|
||||
import(/* webpackChunkName: "side-bar" */ 'components/sideBar/SideBarContainer')
|
||||
import(/* webpackChunkName: "side-bar" */ './components/sideBar/SideBarContainer')
|
||||
);
|
||||
const ExplorerBar = React.lazy(() =>
|
||||
import(/* webpackChunkName: "explorer-bar" */ 'components/explorerBar/ExplorerBarContainer')
|
||||
import(/* webpackChunkName: "explorer-bar" */ './components/explorerBar/ExplorerBarContainer')
|
||||
);
|
||||
|
||||
import './App.scss';
|
||||
const Footer = React.lazy(() => import(/* webpackChunkName: "footer" */ './components/footer'));
|
||||
|
||||
import './App.less';
|
||||
|
||||
const App = (props = {}) => {
|
||||
return (
|
||||
@@ -59,14 +62,9 @@ const App = (props = {}) => {
|
||||
</div>
|
||||
|
||||
<footer className="footer">
|
||||
<span>{`v${process.env.VERSION}`}</span>
|
||||
<span>
|
||||
Ⓒ Bohdan Liashenko
|
||||
{' • '}
|
||||
<a target="_blank" href="https://github.com/Bogdan-Lyashenko/codecrumbs">Github</a>
|
||||
{' • '}
|
||||
<a target="_blank" href="https://codecrumbs.io/">codecrumbs.io</a>
|
||||
</span>
|
||||
<Suspense fallback={null}>
|
||||
<Footer />
|
||||
</Suspense>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getSource, getSourceLayout } from 'core/dataBus/selectors';
|
||||
import { getCheckedState } from 'core/controlsBus/selectors';
|
||||
import { getActiveNamespace } from 'core/namespaceIntegration/selectors';
|
||||
import { getSource, getSourceLayout } from '../../core/dataBus/selectors';
|
||||
import { getCheckedState } from '../../core/controlsBus/selectors';
|
||||
import { getActiveNamespace } from '../../core/namespaceIntegration/selectors';
|
||||
|
||||
import ExplorerBar from './component/ExplorerBar';
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import React from 'react';
|
||||
import { Tree } from 'antd';
|
||||
|
||||
import { FILE_NODE_TYPE } from 'core/constants';
|
||||
import './ExplorerBar.scss';
|
||||
import Tree from 'antd/es/tree';
|
||||
import 'antd/es/tree/style';
|
||||
|
||||
import { FILE_NODE_TYPE } from '../../../core/constants';
|
||||
import './ExplorerBar.less';
|
||||
|
||||
const DirectoryTree = Tree.DirectoryTree;
|
||||
const TreeNode = Tree.TreeNode;
|
||||
|
||||
20
src/public/js/components/footer/index.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
import metaInfo from '../../meta';
|
||||
|
||||
export default () => (
|
||||
<React.Fragment>
|
||||
<span>{`v${metaInfo.version}`}</span>
|
||||
<span>
|
||||
Ⓒ Bohdan Liashenko
|
||||
{' • '}
|
||||
<a target="_blank" href="https://github.com/Bogdan-Lyashenko/codecrumbs">
|
||||
Github
|
||||
</a>
|
||||
{' • '}
|
||||
<a target="_blank" href="https://codecrumbs.io/">
|
||||
codecrumbs.io
|
||||
</a>
|
||||
</span>
|
||||
</React.Fragment>
|
||||
);
|
||||
@@ -1,10 +1,10 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getActiveNamespace } from 'core/namespaceIntegration/selectors';
|
||||
import { getSourceUserChoice, getSource, getProjectMetadata } from 'core/dataBus/selectors';
|
||||
import { toggleSwitch, selectSideBarTab } from 'core/controlsBus/actions';
|
||||
import { getCheckedState, getValuesState } from 'core/controlsBus/selectors';
|
||||
import { getActiveNamespace } from '../../core/namespaceIntegration/selectors';
|
||||
import { getSourceUserChoice, getSource, getProjectMetadata } from '../../core/dataBus/selectors';
|
||||
import { toggleSwitch, selectSideBarTab } from '../../core/controlsBus/actions';
|
||||
import { getCheckedState, getValuesState } from '../../core/controlsBus/selectors';
|
||||
import SideBar from './component/SideBar';
|
||||
|
||||
const SideBarContainer = ({ sideBar, ...otherProps }) => {
|
||||
|
||||
@@ -3,17 +3,17 @@ import classNames from 'classnames';
|
||||
import SyntaxHighlighter from 'react-syntax-highlighter';
|
||||
import { atomOneLight } from 'react-syntax-highlighter/styles/hljs';
|
||||
|
||||
import './index.scss';
|
||||
import './index.less';
|
||||
|
||||
const FONT_SIZE = '12px';
|
||||
const FONT_SIZE = 12;
|
||||
const LINE_HEIGHT = 18;
|
||||
const PADDING_TOP = 5;
|
||||
//TODO: add select with several themes
|
||||
//TODO: scrool to/highlight crumbed lines
|
||||
//https://github.com/conorhastings/react-syntax-highlighter/blob/master/README.md
|
||||
export default class extends React.Component {
|
||||
export default class extends React.PureComponent {
|
||||
fixScroll() {
|
||||
const { dependenciesLines = [], crumbedLines = [] } = this.props;
|
||||
const { dependenciesLines = [], crumbedLines = [], lineHeight } = this.props;
|
||||
if (!this.codeRef || !this.codeRef.scrollTo) {
|
||||
return;
|
||||
}
|
||||
@@ -24,9 +24,11 @@ export default class extends React.Component {
|
||||
? crumbedLines
|
||||
: null;
|
||||
|
||||
lines && this.codeRef.scrollTo(0, (lines[0][0] - 1) * LINE_HEIGHT + PADDING_TOP - 2);
|
||||
lines &&
|
||||
this.codeRef.scrollTo(0, (lines[0][0] - 1) * (lineHeight || LINE_HEIGHT) + PADDING_TOP - 2);
|
||||
}
|
||||
componentDidUpdate(prevProps) {
|
||||
// TODO: don\t do it each time (check real changes)
|
||||
this.fixScroll();
|
||||
}
|
||||
componentDidMount() {
|
||||
@@ -34,7 +36,14 @@ export default class extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { language, code, crumbedLines = [], dependenciesLines = [], limitedHeight } = this.props;
|
||||
const {
|
||||
language,
|
||||
code,
|
||||
crumbedLines = [],
|
||||
dependenciesLines = [],
|
||||
limitedHeight,
|
||||
fontSize
|
||||
} = this.props;
|
||||
|
||||
// TODO: calc height for .Code based on dependenciesLines - it's not always need to be 300 px!!
|
||||
return (
|
||||
@@ -44,7 +53,10 @@ export default class extends React.Component {
|
||||
style={atomOneLight}
|
||||
showLineNumbers={true}
|
||||
wrapLines={true}
|
||||
customStyle={{ fontSize: FONT_SIZE, padding: `${PADDING_TOP}px 0px 5px 5px` }}
|
||||
customStyle={{
|
||||
fontSize: `${fontSize || FONT_SIZE}px`,
|
||||
padding: `${PADDING_TOP}px 0px 5px 5px`
|
||||
}}
|
||||
lineProps={lineNumber => {
|
||||
if (isMatchLineNumber(crumbedLines, lineNumber)) {
|
||||
return { className: 'crumbedLine' };
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Collapse, Alert } from 'antd';
|
||||
|
||||
import { NO_TRAIL_FLOW } from 'shared-with-server-src/constants';
|
||||
import { getCodeCrumbsUserChoice } from 'core/dataBus/selectors';
|
||||
import { getNamespacesList } from 'core/dataBus/selectors';
|
||||
import { gatherFlowStepsData } from 'components/treeDiagram/component/Tree/CodeCrumbs/helpers';
|
||||
import Collapse from 'antd/es/collapse';
|
||||
import 'antd/es/collapse/style';
|
||||
import Alert from 'antd/es/alert';
|
||||
import 'antd/es/alert/style';
|
||||
|
||||
import { NO_TRAIL_FLOW } from '../../../../shared-constants';
|
||||
import { getCodeCrumbsUserChoice } from '../../../../core/dataBus/selectors';
|
||||
import { getSharedFlowStepsData } from '../../../../core/namespaceIntegration/selectors';
|
||||
|
||||
import Code from '../Code';
|
||||
import './index.scss';
|
||||
import './index.less';
|
||||
|
||||
const Panel = Collapse.Panel;
|
||||
|
||||
@@ -30,7 +33,7 @@ const CrumbsTab = props => {
|
||||
header={`[${typeof stepFile.step !== 'undefined' ? stepFile.step : '*'}] ${
|
||||
stepFile.file.path
|
||||
}`}
|
||||
key={i}
|
||||
key={stepFile.crumbNodeLines.join(',')}
|
||||
>
|
||||
<Code
|
||||
language={language}
|
||||
@@ -54,7 +57,6 @@ const CrumbsTab = props => {
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const namespacesList = getNamespacesList(state);
|
||||
const { namespace } = props;
|
||||
|
||||
const {
|
||||
@@ -65,18 +67,14 @@ const mapStateToProps = (state, props) => {
|
||||
namespace
|
||||
});
|
||||
|
||||
const { ccFilesLayoutMapNs, sortedFlowSteps } = gatherFlowStepsData({
|
||||
currentSelectedCrumbedFlowKey,
|
||||
namespacesList,
|
||||
state
|
||||
});
|
||||
const { involvedNsData, sortedFlowSteps } = getSharedFlowStepsData(state);
|
||||
|
||||
if (currentSelectedCrumbedFlowKey === NO_TRAIL_FLOW) {
|
||||
return {
|
||||
flowStepsFiles: getUnTrailedCodecrumbs(
|
||||
currentSelectedCrumbedFlowKey,
|
||||
codeCrumbedFlowsMap,
|
||||
ccFilesLayoutMapNs[namespace]
|
||||
involvedNsData[namespace].codecrumbsLayoutMap
|
||||
)
|
||||
};
|
||||
}
|
||||
@@ -87,7 +85,7 @@ const mapStateToProps = (state, props) => {
|
||||
: sortedFlowSteps
|
||||
).map(item => ({
|
||||
...item,
|
||||
file: ccFilesLayoutMapNs[item.namespace][item.filePath].data
|
||||
file: involvedNsData[item.namespace].codecrumbsLayoutMap[item.filePath].data
|
||||
}))
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Collapse, Alert } from 'antd';
|
||||
|
||||
import { getSource, getSourceUserChoice, getDependenciesUserChoice } from 'core/dataBus/selectors';
|
||||
import Collapse from 'antd/es/collapse';
|
||||
import 'antd/es/collapse/style';
|
||||
import Alert from 'antd/es/alert';
|
||||
import 'antd/es/alert/style';
|
||||
|
||||
import {
|
||||
getSource,
|
||||
getSourceUserChoice,
|
||||
getDependenciesUserChoice
|
||||
} from '../../../../core/dataBus/selectors';
|
||||
|
||||
import Code from '../Code';
|
||||
import {
|
||||
@@ -10,7 +18,7 @@ import {
|
||||
findFileNode,
|
||||
extractExportsForImports
|
||||
} from '../shared/utils';
|
||||
import './index.scss';
|
||||
import './index.less';
|
||||
|
||||
const Panel = Collapse.Panel;
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import React from 'react';
|
||||
|
||||
import { Spin, Alert } from 'antd';
|
||||
import Alert from 'antd/es/alert';
|
||||
import 'antd/es/alert/style';
|
||||
import Spin from 'antd/es/spin';
|
||||
import 'antd/es/spin/style';
|
||||
|
||||
import './index.scss';
|
||||
import './index.less';
|
||||
|
||||
const Styles = {
|
||||
strokeColor: '#00bcd4',
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
import React, { Suspense } from 'react';
|
||||
import { Tabs } from 'antd';
|
||||
import { Skeleton, Alert } from 'antd';
|
||||
|
||||
import { Copy } from 'components/topBar/controls/Copy';
|
||||
import Tabs from 'antd/es/tabs';
|
||||
import 'antd/es/tabs/style';
|
||||
import Skeleton from 'antd/es/skeleton';
|
||||
import 'antd/es/skeleton/style';
|
||||
import Alert from 'antd/es/alert';
|
||||
import 'antd/es/alert/style';
|
||||
|
||||
import { Copy } from '../../topBar/controls/Copy';
|
||||
|
||||
const Code = React.lazy(() => import(/* webpackChunkName: "code" */ './Code'));
|
||||
const DependenciesTab = React.lazy(() =>
|
||||
@@ -13,7 +18,7 @@ const FlowChartTab = React.lazy(() =>
|
||||
import(/* webpackChunkName: "flow-chart-tab" */ './FlowChartTab')
|
||||
);
|
||||
|
||||
import './SideBar.scss';
|
||||
import './SideBar.less';
|
||||
|
||||
const TabPane = Tabs.TabPane;
|
||||
|
||||
@@ -31,7 +36,7 @@ export default ({
|
||||
onTabSelect
|
||||
}) => {
|
||||
const file = selectedNode && filesMap[selectedNode.path];
|
||||
const standaloneNoCode = process.env.STANDALONE && (!file || !file.fileCode);
|
||||
const standaloneNoCode = !process.env.LOCAL && (!file || !file.fileCode);
|
||||
const header = standaloneNoCode ? (
|
||||
<Alert
|
||||
message="No code for this file in standalone mode."
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Icon } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
import Icon from 'antd/es/icon';
|
||||
import 'antd/es/icon/style';
|
||||
|
||||
import copy from 'copy-text-to-clipboard';
|
||||
|
||||
export const Copy = ({ copyText }) => (
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Menu, Dropdown, Button } from 'antd';
|
||||
|
||||
import { NO_TRAIL_FLOW } from 'core/constants';
|
||||
import { selectCodeCrumbedFlow } from 'core/dataBus/actions';
|
||||
import { getCodeCrumbsUserChoice } from 'core/dataBus/selectors';
|
||||
import { getCheckedState } from 'core/controlsBus/selectors';
|
||||
import './index.scss';
|
||||
import Menu from 'antd/es/menu';
|
||||
import 'antd/es/menu/style';
|
||||
import Dropdown from 'antd/es/dropdown';
|
||||
import 'antd/es/dropdown/style';
|
||||
import Button from 'antd/es/button';
|
||||
import 'antd/es/button/style';
|
||||
|
||||
import { NO_TRAIL_FLOW } from '../../../../core/constants';
|
||||
import { selectCodeCrumbedFlow } from '../../../../core/dataBus/actions';
|
||||
import { getCodeCrumbsUserChoice } from '../../../../core/dataBus/selectors';
|
||||
import { getCheckedState } from '../../../../core/controlsBus/selectors';
|
||||
import './index.less';
|
||||
|
||||
const FlowSelect = ({
|
||||
codeCrumbsDiagramOn,
|
||||
|
||||
@@ -1,9 +1,19 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Menu, Dropdown, Button, Icon, Upload } from 'antd';
|
||||
|
||||
import { downloadStore, uploadStore } from 'core/dataBus/actions';
|
||||
import './index.scss';
|
||||
import Menu from 'antd/es/menu';
|
||||
import 'antd/es/menu/style';
|
||||
import Dropdown from 'antd/es/dropdown';
|
||||
import 'antd/es/dropdown/style';
|
||||
import Icon from 'antd/es/icon';
|
||||
import 'antd/es/icon/style';
|
||||
import Button from 'antd/es/button';
|
||||
import 'antd/es/button/style';
|
||||
import Upload from 'antd/es/upload';
|
||||
import 'antd/es/upload/style';
|
||||
|
||||
import { downloadStore, uploadStore } from '../../../../core/dataBus/actions';
|
||||
import './index.less';
|
||||
|
||||
const SettingsControl = ({ onDownload, onUpload }) => {
|
||||
const uploadProps = {
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
import React from 'react';
|
||||
import { Switch, Menu, Dropdown, Icon } from 'antd';
|
||||
|
||||
import { VIEW_TYPES } from 'core/controlsBus/constants';
|
||||
import './ViewSwitch.scss';
|
||||
import Switch from 'antd/es/switch';
|
||||
import 'antd/es/switch/style';
|
||||
import Menu from 'antd/es/menu';
|
||||
import 'antd/es/menu/style';
|
||||
import Dropdown from 'antd/es/dropdown';
|
||||
import 'antd/es/dropdown/style';
|
||||
import Icon from 'antd/es/icon';
|
||||
import 'antd/es/icon/style';
|
||||
|
||||
class ViewSwitch extends React.Component {
|
||||
import { VIEW_TYPES } from '../../../../../core/controlsBus/constants';
|
||||
import './ViewSwitch.less';
|
||||
|
||||
class ViewSwitch extends React.PureComponent {
|
||||
renderMenu() {
|
||||
const {
|
||||
name,
|
||||
@@ -70,7 +78,7 @@ class ViewSwitch extends React.Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { name, itemKey, subMenuItems, checkedState, toggleSwitch } = this.props;
|
||||
const { name, itemKey, subMenuItems, checkedState, disabledState, toggleSwitch } = this.props;
|
||||
|
||||
return (
|
||||
<div className="ViewSwitchItem">
|
||||
@@ -84,6 +92,7 @@ class ViewSwitch extends React.Component {
|
||||
size="small"
|
||||
checked={checkedState[itemKey]}
|
||||
onChange={v => toggleSwitch(itemKey, v)}
|
||||
disabled={disabledState[itemKey]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import FlowSelect from 'components/topBar/controls/FlowSelect/index';
|
||||
import ZoomControl from 'components/topBar/controls/ZoomControl/index';
|
||||
import SettingsControl from 'components/topBar/controls/SettingsControl/index';
|
||||
import FlowSelect from '../../FlowSelect/index';
|
||||
import SettingsControl from '../../SettingsControl/index';
|
||||
|
||||
import ViewSwitch from '../Item/ViewSwitch';
|
||||
import './ViewSwitchList.scss';
|
||||
import './ViewSwitchList.less';
|
||||
|
||||
const ViewSwitchList = props => {
|
||||
const {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
}
|
||||
|
||||
.settingContainer {
|
||||
display: flex;
|
||||
display: none;
|
||||
flex-direction: row;
|
||||
|
||||
.spacer {
|
||||
@@ -26,4 +26,4 @@
|
||||
border-left: 1px solid #d9d9d9;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,16 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { getActiveNamespace } from 'core/namespaceIntegration/selectors';
|
||||
import { getProjectMetadata } from 'core/dataBus/selectors';
|
||||
import { getActiveNamespace } from '../../../../core/namespaceIntegration/selectors';
|
||||
import { getProjectMetadata } from '../../../../core/dataBus/selectors';
|
||||
|
||||
import { CONTROLS_KEYS } from 'core/controlsBus/constants';
|
||||
import { toggleSwitch, fireButtonAction } from 'core/controlsBus/actions';
|
||||
import { getSwitches, getCheckedState, getDisabledState } from 'core/controlsBus/selectors';
|
||||
import { CONTROLS_KEYS } from '../../../../core/controlsBus/constants';
|
||||
import { toggleSwitch, fireButtonAction } from '../../../../core/controlsBus/actions';
|
||||
import {
|
||||
getSwitches,
|
||||
getCheckedState,
|
||||
getDisabledState
|
||||
} from '../../../../core/controlsBus/selectors';
|
||||
|
||||
import ViewSwitchList from './List/ViewSwitchList';
|
||||
|
||||
@@ -17,7 +21,7 @@ const mapStateToProps = state => {
|
||||
: { fullFeaturesSupport: false };
|
||||
|
||||
const switches = getSwitches(state);
|
||||
|
||||
|
||||
return {
|
||||
activeNamespace: namespace,
|
||||
checkedState: getCheckedState(state),
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Button, Icon } from 'antd';
|
||||
|
||||
import Button from 'antd/es/button';
|
||||
import 'antd/es/button/style';
|
||||
|
||||
const ButtonGroup = Button.Group;
|
||||
|
||||
import { setZoom } from 'core/controlsBus/actions';
|
||||
import { getValuesState } from 'core/controlsBus/selectors';
|
||||
import './index.scss';
|
||||
import { setZoom } from '../../../../core/controlsBus/actions';
|
||||
import { getValuesState } from '../../../../core/controlsBus/selectors';
|
||||
import './index.less';
|
||||
|
||||
const ZoomControl = ({ zoom, setZoom }) => {
|
||||
const step = 0.1;
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Breadcrumb, Icon } from 'antd';
|
||||
|
||||
import { FILE_NODE_TYPE } from 'core/constants/index';
|
||||
import { Copy } from 'components/topBar/controls/Copy/index';
|
||||
import { getActiveNamespace } from 'core/namespaceIntegration/selectors';
|
||||
import { getSourceUserChoice, getProjectMetadata } from 'core/dataBus/selectors';
|
||||
import Icon from 'antd/es/icon';
|
||||
import 'antd/es/icon/style';
|
||||
import Breadcrumb from 'antd/es/breadcrumb';
|
||||
import 'antd/es/breadcrumb/style';
|
||||
|
||||
import './SubPanelContainer.scss';
|
||||
import { FILE_NODE_TYPE } from '../../../core/constants/index';
|
||||
import { Copy } from '../controls/Copy/index';
|
||||
import { getActiveNamespace } from '../../../core/namespaceIntegration/selectors';
|
||||
import { getSourceUserChoice, getProjectMetadata } from '../../../core/dataBus/selectors';
|
||||
|
||||
import './SubPanelContainer.less';
|
||||
|
||||
const SubPanelContainer = ({ selectedNode, platformPathSeparator }) => {
|
||||
if (!selectedNode)
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
.TreeDiagramsContainer {
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.MainLoader {
|
||||
@@ -9,4 +12,4 @@
|
||||
padding: 250px;
|
||||
margin-top: 60px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,19 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Spin } from 'antd';
|
||||
import Spin from 'antd/es/spin';
|
||||
import 'antd/es/spin/style';
|
||||
|
||||
import StandalonePlaceholder from './component/StandalonePlaceholder';
|
||||
|
||||
import { getNamespacesList } from 'core/dataBus/selectors';
|
||||
import { getActiveNamespace } from 'core/namespaceIntegration/selectors';
|
||||
import { getNamespacesList } from '../../core/dataBus/selectors';
|
||||
import { getActiveNamespace } from '../../core/namespaceIntegration/selectors';
|
||||
import TreeDiagram from './component/TreeDiagram';
|
||||
|
||||
import './TreeDiagamsContainer.scss';
|
||||
import './TreeDiagamsContainer.less';
|
||||
|
||||
const TreeDiagramsContainer = ({ namespacesList, activeNamespace }) => {
|
||||
if (!namespacesList.length) {
|
||||
return process.env.STANDALONE ? (
|
||||
return !process.env.LOCAL ? (
|
||||
<StandalonePlaceholder />
|
||||
) : (
|
||||
<div className={'MainLoader'}>
|
||||
@@ -23,6 +24,7 @@ const TreeDiagramsContainer = ({ namespacesList, activeNamespace }) => {
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: use ref for TreeDiagram container (on mount set it to store)
|
||||
return (
|
||||
<div className={'TreeDiagramsContainer'}>
|
||||
{namespacesList.map(namespace => (
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { SYMBOL_WIDTH } from 'components/treeDiagram/component/constants';
|
||||
import Arrow from 'components/treeDiagram/component/Icons/Arrow';
|
||||
import './index.scss';
|
||||
import { SYMBOL_WIDTH } from '../constants';
|
||||
import Arrow from '../Icons/Arrow';
|
||||
import './index.less';
|
||||
|
||||
const SINGLE_CRUMB_SHIFT = 22;
|
||||
|
||||
export const PartEdge = props => {
|
||||
const { sourcePosition, parentName } = props;
|
||||
const { sourcePosition, parentName, ccAlightPoint, singleCrumb } = props;
|
||||
|
||||
const nameWidth = SYMBOL_WIDTH * parentName.length;
|
||||
const padding = 17;
|
||||
|
||||
const P1 = { x: sourcePosition.x + nameWidth + padding, y: sourcePosition.y };
|
||||
const P2 = { x: P1.x + padding + 6, y: P1.y };
|
||||
const P2 = { x: ccAlightPoint - padding - 5 + (singleCrumb ? SINGLE_CRUMB_SHIFT : 0), y: P1.y };
|
||||
|
||||
const polylinePoints = [[P1.x, P1.y], [P2.x, P2.y]];
|
||||
|
||||
@@ -28,20 +30,16 @@ export const PartEdge = props => {
|
||||
);
|
||||
};
|
||||
|
||||
export const CodeCrumbEdge = props => {
|
||||
const { sourcePosition, targetPosition, parentName } = props;
|
||||
export const CodeCrumbMultiEdge = props => {
|
||||
const { sourcePosition, targetPosition, ccAlightPoint } = props;
|
||||
|
||||
const nameWidth = SYMBOL_WIDTH * parentName.length;
|
||||
const padding = 40;
|
||||
const edgeTurnDistance = 20;
|
||||
|
||||
const P1 = { x: sourcePosition.x + nameWidth + padding, y: sourcePosition.y };
|
||||
|
||||
const P2 = { x: targetPosition.x - edgeTurnDistance, y: sourcePosition.y };
|
||||
const P3 = { x: targetPosition.x - edgeTurnDistance, y: targetPosition.y };
|
||||
const edgeTurnDistance = SINGLE_CRUMB_SHIFT;
|
||||
const xStart = ccAlightPoint || targetPosition.x;
|
||||
const P2 = { x: xStart - edgeTurnDistance, y: sourcePosition.y };
|
||||
const P3 = { x: xStart - edgeTurnDistance, y: targetPosition.y };
|
||||
const P4 = targetPosition;
|
||||
|
||||
const polylinePoints = [[P1.x, P1.y], [P2.x, P2.y], [P3.x, P3.y], [P4.x, P4.y]];
|
||||
const polylinePoints = [[P2.x, P2.y], [P3.x, P3.y], [P4.x, P4.y]];
|
||||
|
||||
return (
|
||||
<polyline points={polylinePoints.join(', ')} className={'CodeCrumbEdge'} strokeDasharray="2" />
|
||||
@@ -49,23 +47,15 @@ export const CodeCrumbEdge = props => {
|
||||
};
|
||||
|
||||
export const CodeCrumbedFlowEdge = props => {
|
||||
const {
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
sourceName,
|
||||
singleCrumbSource,
|
||||
singleCrumbTarget,
|
||||
selected,
|
||||
onClick
|
||||
} = props;
|
||||
const { sourcePosition, targetPosition, sourceName, selected, onClick } = props;
|
||||
|
||||
const rHalf = 6;
|
||||
const sourcePt = {
|
||||
x: -rHalf + (singleCrumbSource ? sourcePosition.x - 22 : sourcePosition.x),
|
||||
x: -rHalf + sourcePosition.x,
|
||||
y: sourcePosition.y + rHalf
|
||||
};
|
||||
const targetPt = {
|
||||
x: -rHalf + (singleCrumbTarget ? targetPosition.x - 22 : targetPosition.x),
|
||||
x: -rHalf + targetPosition.x,
|
||||
y: targetPosition.y - rHalf
|
||||
};
|
||||
|
||||
@@ -155,7 +145,7 @@ export const CodeCrumbedFlowEdge = props => {
|
||||
y={endPointConfig.y}
|
||||
height={iconSize}
|
||||
width={iconSize}
|
||||
fill={selected ? '#754BC3' : '#e91e63'}
|
||||
fill={selected ? '#754BC3' : '#717070'}
|
||||
/>
|
||||
</g>
|
||||
);
|
||||
@@ -166,8 +156,6 @@ export const ExternalEdge = props => {
|
||||
const {
|
||||
sourcePosition,
|
||||
targetPosition,
|
||||
singleCrumbSource,
|
||||
singleCrumbTarget,
|
||||
topBottom,
|
||||
areaHeight,
|
||||
firstPart,
|
||||
@@ -177,11 +165,11 @@ export const ExternalEdge = props => {
|
||||
|
||||
const rHalf = 6;
|
||||
const sourcePt = {
|
||||
x: -rHalf + (singleCrumbSource ? sourcePosition.x - 22 : sourcePosition.x),
|
||||
x: -rHalf + sourcePosition.x,
|
||||
y: sourcePosition.y + rHalf
|
||||
};
|
||||
const targetPt = {
|
||||
x: -rHalf + (singleCrumbTarget ? targetPosition.x - 22 : targetPosition.x),
|
||||
x: -rHalf + targetPosition.x,
|
||||
y: targetPosition.y - rHalf
|
||||
};
|
||||
|
||||
@@ -231,7 +219,7 @@ export const ExternalEdge = props => {
|
||||
y={targetPt.y - iconSize}
|
||||
height={iconSize}
|
||||
width={iconSize}
|
||||
fill={selected ? '#754BC3' : '#e91e63'}
|
||||
fill={selected ? '#754BC3' : '#717070'}
|
||||
/>
|
||||
)}
|
||||
</g>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { LAYOUT_CONFIG, DepEdgeGroups } from 'components/treeDiagram/component/constants';
|
||||
import Arrow from 'components/treeDiagram/component/Icons/Arrow';
|
||||
import './index.scss';
|
||||
import { LAYOUT_CONFIG, DepEdgeGroups } from '../constants';
|
||||
import Arrow from '../Icons/Arrow';
|
||||
import './index.less';
|
||||
|
||||
const { TOP_LEFT, TOP_RIGHT } = DepEdgeGroups;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import './index.scss';
|
||||
import './index.less';
|
||||
|
||||
export const SourceEdge = props => {
|
||||
const { targetPosition, sourcePosition, disabled, singleChild, selected } = props;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
@import "../animcations.scss";
|
||||
@import "../animcations.less";
|
||||
|
||||
.EdgeMouseHandler {
|
||||
cursor: pointer;
|
||||
@@ -22,7 +22,7 @@
|
||||
}
|
||||
|
||||
.Animation {
|
||||
@extend .FadeIn;
|
||||
&:extend(.FadeIn);
|
||||
}
|
||||
|
||||
.DependenciesEdge {
|
||||
@@ -35,10 +35,10 @@
|
||||
}
|
||||
|
||||
.CodeCrumbEdge {
|
||||
@extend .FadeIn;
|
||||
&:extend(.FadeIn);
|
||||
|
||||
fill: none;
|
||||
stroke: #ff18a6;
|
||||
stroke: #8c8b8b;
|
||||
}
|
||||
|
||||
.CodeCrumbEdge-under-flow {
|
||||
@@ -49,7 +49,7 @@
|
||||
|
||||
.CodeCrumbEdge-flow {
|
||||
fill: none;
|
||||
stroke: #ff18a6;
|
||||
stroke: #717070;
|
||||
}
|
||||
|
||||
.CodeCrumbEdge-flow-selected {
|
||||
@@ -57,8 +57,8 @@
|
||||
}
|
||||
|
||||
.CodeCrumbEdge-flow-source {
|
||||
fill: #ff18a6;
|
||||
stroke: #ff18a6;
|
||||
fill: #717070;
|
||||
stroke: #717070;
|
||||
}
|
||||
|
||||
.CodeCrumbEdge-flow-source-selected {
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import './index.scss';
|
||||
import './index.less';
|
||||
|
||||
const styleUp = {
|
||||
transform: 'rotate(-90deg)',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import './index.scss';
|
||||
import './index.less';
|
||||
|
||||
export default ({ position, selected }) => {
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
|
||||
import './index.scss';
|
||||
import './index.less';
|
||||
|
||||
export const OpenFolder = ({ x, y, width, height, fill }) => (
|
||||
<svg
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@import "../animcations.scss";
|
||||
@import "../animcations.less";
|
||||
|
||||
.Animation {
|
||||
@extend .FadeIn;
|
||||
&:extend(.FadeIn);
|
||||
}
|
||||
|
||||
.CursorPointer {
|
||||
@@ -1,8 +1,7 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import './index.scss';
|
||||
import { SYMBOL_WIDTH } from 'components/treeDiagram/component/constants';
|
||||
import './index.less';
|
||||
|
||||
export const CodeCrumbName = props => {
|
||||
// onMouseOver maybe use onMouseOver to show crumb details in popover
|
||||
@@ -14,12 +13,13 @@ export const CodeCrumbName = props => {
|
||||
cover,
|
||||
flow,
|
||||
flowStep,
|
||||
original,
|
||||
selected,
|
||||
onMouseOver,
|
||||
onClick
|
||||
} = props;
|
||||
|
||||
const textPoint = { x: singleCrumb ? position.x - 22 : position.x, y: position.y };
|
||||
const textPoint = position;
|
||||
const symbolWidth = 6;
|
||||
const locWidth = loc.length ? loc.length * symbolWidth + 3 : 0;
|
||||
|
||||
@@ -74,7 +74,7 @@ export const CodeCrumbName = props => {
|
||||
onClick={onClick}
|
||||
className={'CodeCrumbName-flow'}
|
||||
>
|
||||
{flowStep}
|
||||
{flowStep !== 0 ? flowStep : /#0/.test(original) ? 0 : '*'}
|
||||
</text>
|
||||
</React.Fragment>
|
||||
)) ||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { SYMBOL_WIDTH } from 'components/treeDiagram/component/constants';
|
||||
import { SYMBOL_WIDTH, NODE_NAME_X_SHIFT } from '../constants';
|
||||
|
||||
import FileIcon from 'components/treeDiagram/component/Icons/language/File';
|
||||
import CppFileIcon from 'components/treeDiagram/component/Icons/language/CppFile';
|
||||
import JavaScriptFileIcon from 'components/treeDiagram/component/Icons/language/JavaScriptFile';
|
||||
import PythonFileIcon from 'components/treeDiagram/component/Icons/language/PythonFile';
|
||||
import FileIcon from '../Icons/language/File';
|
||||
import CppFileIcon from '../Icons/language/CppFile';
|
||||
import JavaScriptFileIcon from '../Icons/language/JavaScriptFile';
|
||||
import PythonFileIcon from '../Icons/language/PythonFile';
|
||||
|
||||
import DepCirclesIcon from 'components/treeDiagram/component/Icons/DepCircles';
|
||||
import './index.scss';
|
||||
import DepCirclesIcon from '../Icons/DepCircles';
|
||||
import './index.less';
|
||||
|
||||
const getFileIcon = ({ position, iconSize, language }) => {
|
||||
switch (language) {
|
||||
@@ -85,12 +85,12 @@ export const FileName = props => {
|
||||
<rect
|
||||
x={position.x + 3}
|
||||
y={position.y - 3}
|
||||
width={16}
|
||||
width={NODE_NAME_X_SHIFT}
|
||||
height={5}
|
||||
className={'NodeText-cover'}
|
||||
/>
|
||||
<rect
|
||||
x={position.x + 16}
|
||||
x={position.x + NODE_NAME_X_SHIFT}
|
||||
y={position.y - 8}
|
||||
width={nameWidth}
|
||||
height={16}
|
||||
@@ -112,7 +112,7 @@ export const FileName = props => {
|
||||
<g>
|
||||
<title>{path}</title>
|
||||
<text
|
||||
x={position.x + 16}
|
||||
x={position.x + NODE_NAME_X_SHIFT}
|
||||
y={position.y + 5}
|
||||
className={classNames('NodeText-file-name', {
|
||||
'NodeText-file-name-purple': purple,
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { FOLDER_OPEN_STATE } from 'core/constants';
|
||||
import {
|
||||
OpenFolder as OpenFolderIcon,
|
||||
CloseFolder as CloseFolderIcon
|
||||
} from 'components/treeDiagram/component/Icons/Folder';
|
||||
import { FOLDER_OPEN_STATE } from '../../../../core/constants';
|
||||
import { OpenFolder as OpenFolderIcon, CloseFolder as CloseFolderIcon } from '../Icons/Folder';
|
||||
|
||||
import './index.scss';
|
||||
import { SYMBOL_WIDTH } from 'components/treeDiagram/component/constants';
|
||||
import './index.less';
|
||||
import { SYMBOL_WIDTH } from '../constants';
|
||||
|
||||
export const FolderName = props => {
|
||||
const { position, name, cover, disabled, openedState, onNodeClick } = props;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
@import "../animcations.scss";
|
||||
@import "../animcations.less";
|
||||
|
||||
.CodeCrumbNode {
|
||||
@extend .FadeIn;
|
||||
&:extend(.FadeIn);
|
||||
}
|
||||
|
||||
.FileNode, .FolderNode {
|
||||
@extend .FadeIn;
|
||||
&:extend(.FadeIn);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
|
||||
.CodeCrumbName-flow-step {
|
||||
fill: #ff18a6;
|
||||
stroke: #e91e63;
|
||||
stroke: #ff18a6;
|
||||
}
|
||||
|
||||
.CodeCrumbName-flow-step-selected {
|
||||
@@ -1,9 +1,13 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Upload, Icon } from 'antd';
|
||||
|
||||
import { uploadStore } from 'core/dataBus/actions';
|
||||
import './index.scss';
|
||||
import Upload from 'antd/es/upload';
|
||||
import 'antd/es/upload/style';
|
||||
import Icon from 'antd/es/icon';
|
||||
import 'antd/es/icon/style';
|
||||
|
||||
import { uploadStore } from '../../../../core/dataBus/actions';
|
||||
import './index.less';
|
||||
|
||||
const Dragger = Upload.Dragger;
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import { getCheckedState } from 'core/controlsBus/selectors';
|
||||
import { getCodeCrumbsUserChoice, getSourceLayout } from 'core/dataBus/selectors';
|
||||
import { isCodeCrumbSelected } from '../helpers';
|
||||
|
||||
import './index.scss';
|
||||
|
||||
const DetailsComponent = props => {
|
||||
const { name, details, position, singleCrumb, selected } = props;
|
||||
|
||||
// TODO: refactor
|
||||
const nameWidth = name ? name.length * 7.5 : 100;
|
||||
return (
|
||||
<div
|
||||
className={classNames('CcDetailsContainer', { CcDetailsSelected: selected })}
|
||||
style={{
|
||||
left: position.x - (singleCrumb ? 20 : 0),
|
||||
top: position.y + 8,
|
||||
width: nameWidth + 'px'
|
||||
}}
|
||||
>
|
||||
{details}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const DetailsSet = ({
|
||||
detailsEnabled,
|
||||
codecrumbsLayoutMap,
|
||||
shiftToCenterPoint,
|
||||
selectedCrumbedFlowKey,
|
||||
selectedCcFlowEdgeNodes
|
||||
}) => {
|
||||
if (!detailsEnabled) return null;
|
||||
|
||||
const detailsPanels = [];
|
||||
|
||||
Object.keys(codecrumbsLayoutMap).forEach(filePath => {
|
||||
const codecrumbs = (codecrumbsLayoutMap[filePath].children || [])
|
||||
.filter(({ data }) => data.params.flow === selectedCrumbedFlowKey)
|
||||
.map(({ data, x, y }) => ({
|
||||
name: data.name,
|
||||
details: data.params.details,
|
||||
filePath,
|
||||
x,
|
||||
y
|
||||
}));
|
||||
|
||||
codecrumbs.forEach((ccNode, i) => {
|
||||
if (!ccNode || !ccNode.details) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const [nX, nY] = [ccNode.y, ccNode.x];
|
||||
const position = shiftToCenterPoint(nX, nY);
|
||||
|
||||
detailsPanels.push(
|
||||
<DetailsComponent
|
||||
key={filePath + i}
|
||||
details={ccNode.details}
|
||||
name={ccNode.name}
|
||||
position={position}
|
||||
selected={isCodeCrumbSelected(selectedCcFlowEdgeNodes, ccNode)}
|
||||
singleCrumb={codecrumbs.length === 1}
|
||||
/>
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
return <React.Fragment>{detailsPanels}</React.Fragment>;
|
||||
};
|
||||
|
||||
const mapStateToProps = (state, props) => {
|
||||
const { codeCrumbsMinimize, codeCrumbsDetails } = getCheckedState(state);
|
||||
const { namespace } = props;
|
||||
|
||||
const namespaceProps = { namespace };
|
||||
const { codecrumbsLayoutMap } = getSourceLayout(state, namespaceProps);
|
||||
const { selectedCrumbedFlowKey, selectedCcFlowEdgeNodes } = getCodeCrumbsUserChoice(
|
||||
state,
|
||||
namespaceProps
|
||||
);
|
||||
|
||||
return {
|
||||
codecrumbsLayoutMap,
|
||||
selectedCrumbedFlowKey,
|
||||
detailsEnabled: !codeCrumbsMinimize && codeCrumbsDetails,
|
||||
selectedCcFlowEdgeNodes
|
||||
};
|
||||
};
|
||||
export default connect(mapStateToProps)(DetailsSet);
|
||||