diff --git a/.frontmatter/content/mediaDb.json b/.frontmatter/content/mediaDb.json
new file mode 100644
index 00000000..9e26dfee
--- /dev/null
+++ b/.frontmatter/content/mediaDb.json
@@ -0,0 +1 @@
+{}
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1dc73ce0..afee4c46 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,32 @@
# Change Log
+## [6.0.0] - 2022-01-xx - [Release Notes](https://beta.frontmatter.codes/updates/v6.0.0)
+
+### โจ New features
+
+- [#193](https://github.com/estruyf/vscode-front-matter/issues/193): Support added for editing data files.
+- [#197](https://github.com/estruyf/vscode-front-matter/issues/197): Support for multi-dimensional content type fields on content creation and editing.
+- [#225](https://github.com/estruyf/vscode-front-matter/issues/225): Placeholder support for front matter field values (template and content type).
+- [#226](https://github.com/estruyf/vscode-front-matter/issues/226): Ability to specify the local server start command and trigger it from the UI.
+- [#227](https://github.com/estruyf/vscode-front-matter/issues/227): Specify the file types to support with the new `frontMatter.content.supportedFileTypes` setting.
+- [#228](https://github.com/estruyf/vscode-front-matter/issues/228): Show bulk button actions in panel and dashboard view.
+- [#231](https://github.com/estruyf/vscode-front-matter/issues/231): Once you authenticate via GitHub as a supporter, the support links will be hidden from the UI.
+
+### ๐จ Enhancements
+
+- Added default field value for content type fields
+- HMR support for panel webview development
+- Added reveal media file action
+- [#187](https://github.com/estruyf/vscode-front-matter/issues/187): Svelte support with the [#227](https://github.com/estruyf/vscode-front-matter/issues/227) features has been added.
+- [#198](https://github.com/estruyf/vscode-front-matter/issues/198): Additional media sort options (alt, caption, and size).
+- [#230](https://github.com/estruyf/vscode-front-matter/issues/230): JSON front matter support added.
+- [#233](https://github.com/estruyf/vscode-front-matter/issues/233): Partial update when a page is updated.
+
+### ๐ Fixes
+
+- [#234](https://github.com/estruyf/vscode-front-matter/issues/234): Fix for multi-word keywords
+- [#235](https://github.com/estruyf/vscode-front-matter/issues/235): Fix for reselecting the previously removed value from a choice field
+
## [5.10.0] - 2022-01-10
### ๐จ Enhancements
diff --git a/README.beta.md b/README.beta.md
index fb5916bc..a70cbd87 100644
--- a/README.beta.md
+++ b/README.beta.md
@@ -28,30 +28,50 @@
-## What is Front Matter?
+## โ What is Front Matter?
-Front Matter BETA is an essential Visual Studio Code extension that simplifies working and managing your markdown articles. We created the extension to support many static-site generators like Hugo, Jekyll, Hexo, NextJs, Gatsby, and more.
+Front Matter is a CMS that runs within Visual Studio Code. It gives you the power and control of a full-blown CMS while also providing you the flexibility and speed of the static site generator of your choice. Jump right into editing and creating content with Front Matter and be able to preview it straight in VS Code.
-The extension brings Content Management System (CMS) capabilities straight within Visual Studio Code. For example, you can keep a list of the used tags, categories, create content, and so much more.
+The extension supports various static-site generators and frameworks like Hugo, Jekyll, Hexo, NextJs, Gatsby, and more.
-Our main extension features are:
+A couple of our extension highlights that hopefully get you interested in giving Front Matter a try:
-- Page dashboard where you can get an overview of all your markdown pages. You can use it to search, filter, sort your contents.
-- Site preview within Visual Studio Code
+- Content, data, and media management
+ - Search, filter, sort, etc. all your content
+ - Create new content
+ - Supporting tools to edit content and media
+- Preview your site/content straight in Visual Studio Code
- SEO checks for title, description, and keywords
-- Support for custom actions/scripts
-- and many more
+- Extensibility
+ - As we know, we cannot support all use cases. We provide a way to extend the functionality of the extension to your needs
+- and many more features ...
+
+> Missing something? Let us know by opening an issue on the [GitHub repository](https://github.com/estruyf/vscode-front-matter/issues/new/choose)
-
+
> If you see something missing in your article creation flow, please feel free to reach out.
+**Version 6**
+
+In this version, we introduced the new data files/folders dashboard. You can find more information about the release in our [v6.0.0 release notes](https://frontmatter.codes/updates/v6.0.0).
+
+
+
+
+
+> Data files/folders are pieces of content that do not belong to any markdown content, but live on their own. Most of the time, these data files are used to store additional information about your project/blog/website that will be used to render the content.
+
**Version 5**
The new media dashboard redesign got introduced + support for setting metadata on media files [v5.0.0 release notes](https://frontmatter.codes/updates/v5.0.0).
+
+
+
+
**Version 4**
Support for Team level settings, content-types, and image support. Get to know more at: [v4.0.0 release notes](https://frontmatter.codes/updates/v4_0_0).
@@ -70,7 +90,7 @@ In version v2 we released the re-designed sidebar panel with improved SEO suppor
-## Installation
+## โ๏ธ Installation
You can get the extension via:
@@ -80,23 +100,54 @@ You can get the extension via:
> **Info**: The docs can be found on [frontmatter.codes](https://frontmatter.codes).
-### Beta version
+### ๐งช Beta version
If you have the courage to test out the beta features, we made available a beta version as well. You can install this via:
-- The VS Code marketplace: [VS Code Marketplace - Front Matter BETA](https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter-beta).
-- The extension CLI: `ext install eliostruyf.vscode-front-matter-beta`
-- Or by clicking on the following link: open extension in VS Code
+- Uninstall the main Front Matter version
+- Install the beta version
+ - VS Code marketplace: [VS Code Marketplace - Front Matter BETA](https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter-beta).
+ - The extension CLI: `ext install eliostruyf.vscode-front-matter-beta`
+ - Or by clicking on the following link: open extension in VS Code
> **Info**: The BETA docs can be found on [beta.frontmatter.codes](https://beta.frontmatter.codes).
-## Documentation
+## ๐ Documentation
-
+All documentation can be found on [frontmatter.codes](https://frontmatter.codes).
+
+Documentation repository: [GitHub - Front Matter DOCs](https://github.com/FrontMatter/web-documentation-nextjs)
+
+## ๐ช Contributing
+
+Pull requests are welcome. Please open an issue first to discuss what you would like to change, or which problem you would like to fix. This makes it easier for us to follow-up and plan for future releases.
+
+You can always help us improve the extension in varous ways like:
+
+- Testing out the extension and providing feedback
+- Reporting issues and bugs
+- Suggesting new features
+- Fixing an issue
+- Updating documentation
+- UI improvements
+- Tutorials
+- etc.
+
+Eager to start contributing? Great ๐คฉ, you can contribute to the following projects:
+
+- [Extension](https://github.com/estruyf/vscode-front-matter)
+- [Documentation](https://github.com/FrontMatter/web-documentation-nextjs)
+- [Sample Projects](https://github.com/FrontMatter/project-samples)
+
+## ๐ Show the work you are using Front Matter
+
+Are you using Front Matter and are you interested in showing for which websites you use it? You can show your work by opening a [showcase issue](https://github.com/estruyf/vscode-front-matter/issues/new?assignees=&labels=&template=showcase.md&title=Showcase%3A+).
+
+You can open showcase issues for the following things:
+
+- Show the website for which you use Front Matter;
+- Share an article/video/webcast/... that explains how you use Front Matter;
+- Got something else to share? Open an issue and we can see where it fits on our website.
## ๐ Contributors ๐ค
@@ -109,6 +160,9 @@ If you have the courage to test out the beta features, we made available a beta
## ๐ค Backers & Sponsors ๐ ๐ค
+
+
+
@@ -128,6 +182,9 @@ If you have the courage to test out the beta features, we made available a beta
+## ๐ License
+
+[MIT](./LICENSE)
diff --git a/README.md b/README.md
index 76f6cb36..9662abd9 100644
--- a/README.md
+++ b/README.md
@@ -26,30 +26,50 @@
-## What is Front Matter?
+## โ What is Front Matter?
-Front Matter is an essential Visual Studio Code extension that simplifies working and managing your markdown articles. We created the extension to support many static-site generators like Hugo, Jekyll, Hexo, NextJs, Gatsby, and more.
+Front Matter is a CMS that runs within Visual Studio Code. It gives you the power and control of a full-blown CMS while also providing you the flexibility and speed of the static site generator of your choice. Jump right into editing and creating content with Front Matter and be able to preview it straight in VS Code.
-The extension brings Content Management System (CMS) capabilities straight within Visual Studio Code. For example, you can keep a list of the used tags, categories, create content, and so much more.
+The extension supports various static-site generators and frameworks like Hugo, Jekyll, Hexo, NextJs, Gatsby, and more.
-Our main extension features are:
+A couple of our extension highlights that hopefully get you interested in giving Front Matter a try:
-- Page dashboard where you can get an overview of all your markdown pages. You can use it to search, filter, sort your contents.
-- Site preview within Visual Studio Code
+- Content, data, and media management
+ - Search, filter, sort, etc. all your content
+ - Create new content
+ - Supporting tools to edit content and media
+- Preview your site/content straight in Visual Studio Code
- SEO checks for title, description, and keywords
-- Support for custom actions/scripts
-- and many more
+- Extensibility
+ - As we know, we cannot support all use cases. We provide a way to extend the functionality of the extension to your needs
+- and many more features ...
+
+> Missing something? Let us know by opening an issue on the [GitHub repository](https://github.com/estruyf/vscode-front-matter/issues/new/choose)
-
+
> If you see something missing in your article creation flow, please feel free to reach out.
+**Version 6**
+
+In this version, we introduced the new data files/folders dashboard. You can find more information about the release in our [v6.0.0 release notes](https://frontmatter.codes/updates/v6.0.0).
+
+
+
+
+
+> Data files/folders are pieces of content that do not belong to any markdown content, but live on their own. Most of the time, these data files are used to store additional information about your project/blog/website that will be used to render the content.
+
**Version 5**
The new media dashboard redesign got introduced + support for setting metadata on media files [v5.0.0 release notes](https://frontmatter.codes/updates/v5.0.0).
+
+
+
+
**Version 4**
Support for Team level settings, content-types, and image support. Get to know more at: [v4.0.0 release notes](https://frontmatter.codes/updates/v4_0_0).
@@ -68,7 +88,7 @@ In version v2 we released the re-designed sidebar panel with improved SEO suppor
-## Installation
+## โ๏ธ Installation
You can get the extension via:
@@ -78,23 +98,54 @@ You can get the extension via:
> **Info**: The docs can be found on [frontmatter.codes](https://frontmatter.codes).
-### Beta version
+### ๐งช Beta version
If you have the courage to test out the beta features, we made available a beta version as well. You can install this via:
-- The VS Code marketplace: [VS Code Marketplace - Front Matter BETA](https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter-beta).
-- The extension CLI: `ext install eliostruyf.vscode-front-matter-beta`
-- Or by clicking on the following link: open extension in VS Code
+- Uninstall the main Front Matter version
+- Install the beta version
+ - VS Code marketplace: [VS Code Marketplace - Front Matter BETA](https://marketplace.visualstudio.com/items?itemName=eliostruyf.vscode-front-matter-beta).
+ - The extension CLI: `ext install eliostruyf.vscode-front-matter-beta`
+ - Or by clicking on the following link: open extension in VS Code
> **Info**: The BETA docs can be found on [beta.frontmatter.codes](https://beta.frontmatter.codes).
-## Documentation
+## ๐ Documentation
-
+All documentation can be found on [frontmatter.codes](https://frontmatter.codes).
+
+Documentation repository: [GitHub - Front Matter DOCs](https://github.com/FrontMatter/web-documentation-nextjs)
+
+## ๐ช Contributing
+
+Pull requests are welcome. Please open an issue first to discuss what you would like to change, or which problem you would like to fix. This makes it easier for us to follow-up and plan for future releases.
+
+You can always help us improve the extension in varous ways like:
+
+- Testing out the extension and providing feedback
+- Reporting issues and bugs
+- Suggesting new features
+- Fixing an issue
+- Updating documentation
+- UI improvements
+- Tutorials
+- etc.
+
+Eager to start contributing? Great ๐คฉ, you can contribute to the following projects:
+
+- [Extension](https://github.com/estruyf/vscode-front-matter)
+- [Documentation](https://github.com/FrontMatter/web-documentation-nextjs)
+- [Sample Projects](https://github.com/FrontMatter/project-samples)
+
+## ๐ Show the work you are using Front Matter
+
+Are you using Front Matter and are you interested in showing for which websites you use it? You can show your work by opening a [showcase issue](https://github.com/estruyf/vscode-front-matter/issues/new?assignees=&labels=&template=showcase.md&title=Showcase%3A+).
+
+You can open showcase issues for the following things:
+
+- Show the website for which you use Front Matter;
+- Share an article/video/webcast/... that explains how you use Front Matter;
+- Got something else to share? Open an issue and we can see where it fits on our website.
## ๐ Contributors ๐ค
@@ -107,6 +158,9 @@ If you have the courage to test out the beta features, we made available a beta
## ๐ค Backers & Sponsors ๐ ๐ค
+
+
+
@@ -126,6 +180,10 @@ If you have the courage to test out the beta features, we made available a beta
+## ๐ License
+
+[MIT](./LICENSE)
+
diff --git a/assets/media/styles.css b/assets/media/styles.css
index d9cb4f9f..518f898a 100644
--- a/assets/media/styles.css
+++ b/assets/media/styles.css
@@ -446,12 +446,33 @@ input:checked + .field__toggle__slider:before {
margin-bottom: 1rem;
}
+.vscode-dark .metadata_field__box {
+ background: rgba(255, 255, 255, 0.1);
+ border: 2px dashed rgba(255, 255, 255, 0.2);
+}
+
+.vscode-light .metadata_field__box {
+ background: rgba(0, 0, 0, 0.1);
+ border: 2px dashed rgba(0, 0, 0, 0.2);
+}
+
+.metadata_field__box {
+ background: rgba(255, 255, 255, 0.1);
+ border: 2px dashed rgba(255, 255, 255, 0.2);
+ margin-bottom: .5rem;
+ padding: .5rem 1rem;
+}
+
.metadata_field__label {
display: flex;
align-items: center;
margin-bottom: .5rem;
}
+.metadata_field__label.metadata_field__label_parent {
+ justify-content: center;
+}
+
.metadata_field__label svg {
margin-right: .5rem;
}
@@ -638,6 +659,14 @@ input:checked + .field__toggle__slider:before {
margin-top: .5rem;
}
+.vscode-light .metadata_field__preview_image__preview {
+ background: rgba(0, 0, 0, 0.1);
+}
+
+.vscode-dark .metadata_field__preview_image__preview {
+ background: rgba(255, 255, 255, 0.1);
+}
+
.metadata_field__preview_image__preview {
background-color: var(--vscode-button-secondaryBackground);
display: flex;
diff --git a/assets/v5.9.0/media-dashboard.png b/assets/v5.9.0/media-dashboard.png
new file mode 100644
index 00000000..1bc138df
Binary files /dev/null and b/assets/v5.9.0/media-dashboard.png differ
diff --git a/assets/v6.0.0/content-preview.png b/assets/v6.0.0/content-preview.png
new file mode 100644
index 00000000..7dfeb057
Binary files /dev/null and b/assets/v6.0.0/content-preview.png differ
diff --git a/assets/v6.0.0/data-dashboard.png b/assets/v6.0.0/data-dashboard.png
new file mode 100644
index 00000000..695d4cdd
Binary files /dev/null and b/assets/v6.0.0/data-dashboard.png differ
diff --git a/package-lock.json b/package-lock.json
index de56a859..e50bb758 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,19 +1,23 @@
{
"name": "vscode-front-matter-beta",
- "version": "5.10.0",
+ "version": "6.0.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "vscode-front-matter-beta",
- "version": "5.10.0",
+ "version": "6.0.0",
"license": "MIT",
+ "dependencies": {
+ "node-fetch": "^2.6.7"
+ },
"devDependencies": {
"@bendera/vscode-webview-elements": "0.6.2",
"@estruyf/vscode": "0.0.2",
"@headlessui/react": "^1.4.1",
"@heroicons/react": "1.0.4",
"@iarna/toml": "2.2.3",
+ "@octokit/rest": "^18.12.0",
"@sentry/react": "^6.13.3",
"@sentry/tracing": "^6.13.3",
"@tailwindcss/forms": "^0.3.3",
@@ -22,6 +26,7 @@
"@types/lodash.uniqby": "4.7.6",
"@types/mocha": "^5.2.6",
"@types/node": "10.17.48",
+ "@types/node-fetch": "^2.5.12",
"@types/react": "17.0.0",
"@types/react-datepicker": "^4.1.7",
"@types/react-dom": "17.0.0",
@@ -29,6 +34,8 @@
"@vscode/codicons": "0.0.20",
"@vscode/webview-ui-toolkit": "^0.8.1",
"@webpack-cli/serve": "^1.6.0",
+ "ajv": "^8.8.2",
+ "array-move": "^4.0.0",
"autoprefixer": "^10.3.2",
"css-loader": "5.2.7",
"date-fns": "2.23.0",
@@ -47,17 +54,24 @@
"path-browserify": "^1.0.1",
"postcss": "^8.3.6",
"postcss-loader": "4.3.0",
+ "postcss-nested": "^5.0.6",
"react": "17.0.1",
"react-datepicker": "4.2.1",
"react-dom": "17.0.1",
"react-dropzone": "^11.3.4",
+ "react-sortable-hoc": "^2.0.0",
+ "react-toastify": "^8.1.0",
"recoil": "^0.4.1",
"rimraf": "^3.0.2",
"style-loader": "2.0.0",
"tailwindcss": "^2.2.7",
"ts-loader": "8.0.3",
"tslint": "6.1.3",
- "typescript": "4.0.2",
+ "typescript": "^4.5.4",
+ "uniforms": "^3.7.0",
+ "uniforms-antd": "^3.7.0",
+ "uniforms-bridge-json-schema": "^3.7.0",
+ "uniforms-unstyled": "^3.7.0",
"url-join-ts": "^1.0.5",
"wc-react": "github:estruyf/wc-react",
"webpack": "^5.65.0",
@@ -69,6 +83,60 @@
"vscode": "^1.63.0"
}
},
+ "node_modules/@ant-design/colors": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz",
+ "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@ctrl/tinycolor": "^3.4.0"
+ }
+ },
+ "node_modules/@ant-design/icons": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-4.7.0.tgz",
+ "integrity": "sha512-aoB4Z7JA431rt6d4u+8xcNPPCrdufSRMUOpxa1ab6mz1JCQZOEVolj2WVs/tDFmN62zzK30mNelEsprLYsSF3g==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@ant-design/colors": "^6.0.0",
+ "@ant-design/icons-svg": "^4.2.1",
+ "@babel/runtime": "^7.11.2",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.9.4"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "peerDependencies": {
+ "react": ">=16.0.0",
+ "react-dom": ">=16.0.0"
+ }
+ },
+ "node_modules/@ant-design/icons-svg": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.2.1.tgz",
+ "integrity": "sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/@ant-design/icons/node_modules/rc-util": {
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
+ "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "react-is": "^16.12.0",
+ "shallowequal": "^1.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
@@ -113,6 +181,16 @@
"lit-element": "^2.5.1"
}
},
+ "node_modules/@ctrl/tinycolor": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz",
+ "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"node_modules/@discoveryjs/json-ext": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz",
@@ -218,6 +296,28 @@
"resolve": "~1.19.0"
}
},
+ "node_modules/@microsoft/tsdoc-config/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -253,6 +353,156 @@
"node": ">= 8"
}
},
+ "node_modules/@octokit/auth-token": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
+ "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^6.0.3"
+ }
+ },
+ "node_modules/@octokit/core": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
+ "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/auth-token": "^2.4.4",
+ "@octokit/graphql": "^4.5.8",
+ "@octokit/request": "^5.6.0",
+ "@octokit/request-error": "^2.0.5",
+ "@octokit/types": "^6.0.3",
+ "before-after-hook": "^2.2.0",
+ "universal-user-agent": "^6.0.0"
+ }
+ },
+ "node_modules/@octokit/endpoint": {
+ "version": "6.0.12",
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
+ "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^6.0.3",
+ "is-plain-object": "^5.0.0",
+ "universal-user-agent": "^6.0.0"
+ }
+ },
+ "node_modules/@octokit/endpoint/node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@octokit/graphql": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
+ "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/request": "^5.6.0",
+ "@octokit/types": "^6.0.3",
+ "universal-user-agent": "^6.0.0"
+ }
+ },
+ "node_modules/@octokit/openapi-types": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz",
+ "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==",
+ "dev": true
+ },
+ "node_modules/@octokit/plugin-paginate-rest": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz",
+ "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^6.34.0"
+ },
+ "peerDependencies": {
+ "@octokit/core": ">=2"
+ }
+ },
+ "node_modules/@octokit/plugin-request-log": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
+ "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
+ "dev": true,
+ "peerDependencies": {
+ "@octokit/core": ">=3"
+ }
+ },
+ "node_modules/@octokit/plugin-rest-endpoint-methods": {
+ "version": "5.13.0",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz",
+ "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^6.34.0",
+ "deprecation": "^2.3.1"
+ },
+ "peerDependencies": {
+ "@octokit/core": ">=3"
+ }
+ },
+ "node_modules/@octokit/request": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
+ "integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/endpoint": "^6.0.1",
+ "@octokit/request-error": "^2.1.0",
+ "@octokit/types": "^6.16.1",
+ "is-plain-object": "^5.0.0",
+ "node-fetch": "^2.6.1",
+ "universal-user-agent": "^6.0.0"
+ }
+ },
+ "node_modules/@octokit/request-error": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
+ "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^6.0.3",
+ "deprecation": "^2.0.0",
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/@octokit/request/node_modules/is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@octokit/rest": {
+ "version": "18.12.0",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
+ "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/core": "^3.5.1",
+ "@octokit/plugin-paginate-rest": "^2.16.8",
+ "@octokit/plugin-request-log": "^1.0.4",
+ "@octokit/plugin-rest-endpoint-methods": "^5.12.0"
+ }
+ },
+ "node_modules/@octokit/types": {
+ "version": "6.34.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz",
+ "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/openapi-types": "^11.2.0"
+ }
+ },
"node_modules/@polka/url": {
"version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
@@ -515,6 +765,16 @@
"integrity": "sha512-Agl6xbYP6FOMDeAsr3QVZ+g7Yzg0uhPHWx0j5g4LFdUBHVtqtU+gH660k/lCEe506jJLOGbEzsnqPDTZGJQLag==",
"dev": true
},
+ "node_modules/@types/node-fetch": {
+ "version": "2.5.12",
+ "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
+ "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*",
+ "form-data": "^3.0.0"
+ }
+ },
"node_modules/@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
@@ -905,14 +1165,14 @@
}
},
"node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "8.8.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
+ "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
"dev": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
},
"funding": {
@@ -937,37 +1197,6 @@
}
}
},
- "node_modules/ajv-formats/node_modules/ajv": {
- "version": "8.8.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
- "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/ajv-formats/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
- "node_modules/ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "peerDependencies": {
- "ajv": "^6.9.1"
- }
- },
"node_modules/ansi-html-community": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
@@ -1004,6 +1233,740 @@
"node": ">=4"
}
},
+ "node_modules/antd": {
+ "version": "4.18.3",
+ "resolved": "https://registry.npmjs.org/antd/-/antd-4.18.3.tgz",
+ "integrity": "sha512-EoCMY8pFKX9IVAc0Bdi3DWR03IIOHa6mTZALOGjrKbPm3kbrcvoBTCNXq4BMeVA1dZbMeoBw46peeJLyMp2avw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@ant-design/colors": "^6.0.0",
+ "@ant-design/icons": "^4.7.0",
+ "@ant-design/react-slick": "~0.28.1",
+ "@babel/runtime": "^7.12.5",
+ "@ctrl/tinycolor": "^3.4.0",
+ "array-tree-filter": "^2.1.0",
+ "classnames": "^2.2.6",
+ "copy-to-clipboard": "^3.2.0",
+ "lodash": "^4.17.21",
+ "memoize-one": "^6.0.0",
+ "moment": "^2.25.3",
+ "rc-cascader": "~3.0.0-alpha.3",
+ "rc-checkbox": "~2.3.0",
+ "rc-collapse": "~3.1.0",
+ "rc-dialog": "~8.6.0",
+ "rc-drawer": "~4.4.2",
+ "rc-dropdown": "~3.2.0",
+ "rc-field-form": "~1.22.0-2",
+ "rc-image": "~5.2.5",
+ "rc-input-number": "~7.3.0",
+ "rc-mentions": "~1.6.1",
+ "rc-menu": "~9.2.1",
+ "rc-motion": "^2.4.4",
+ "rc-notification": "~4.5.7",
+ "rc-pagination": "~3.1.9",
+ "rc-picker": "~2.5.17",
+ "rc-progress": "~3.2.1",
+ "rc-rate": "~2.9.0",
+ "rc-resize-observer": "^1.1.2",
+ "rc-select": "~14.0.0-alpha.15",
+ "rc-slider": "~9.7.4",
+ "rc-steps": "~4.1.0",
+ "rc-switch": "~3.2.0",
+ "rc-table": "~7.22.2",
+ "rc-tabs": "~11.10.0",
+ "rc-textarea": "~0.3.0",
+ "rc-tooltip": "~5.1.1",
+ "rc-tree": "~5.3.5",
+ "rc-tree-select": "~5.0.0-alpha.2",
+ "rc-trigger": "^5.2.10",
+ "rc-upload": "~4.3.0",
+ "rc-util": "^5.14.0",
+ "scroll-into-view-if-needed": "^2.2.25"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/ant-design"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/@ant-design/react-slick": {
+ "version": "0.28.4",
+ "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-0.28.4.tgz",
+ "integrity": "sha512-j9eAHTn7GxbXUFNknJoHS2ceAsqrQi2j8XykjZE1IXCD8kJF+t28EvhBLniDpbOsBk/3kjalnhriTfZcjBHNqg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.4",
+ "classnames": "^2.2.5",
+ "json2mq": "^0.2.0",
+ "lodash": "^4.17.21",
+ "resize-observer-polyfill": "^1.5.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-cascader": {
+ "version": "3.0.0-alpha.7",
+ "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.0.0-alpha.7.tgz",
+ "integrity": "sha512-hHhPJW9ll41vMd36gmZWYem9749KI9cW51tPQWCp/AS98wgdz/m71y0eXzHIsiVrsIq54sAvccmHK/ZwrRi13Q==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "array-tree-filter": "^2.1.0",
+ "classnames": "^2.3.1",
+ "rc-select": "~14.0.0-alpha.8",
+ "rc-tree": "~5.3.4",
+ "rc-util": "^5.6.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-checkbox": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-2.3.2.tgz",
+ "integrity": "sha512-afVi1FYiGv1U0JlpNH/UaEXdh6WUJjcWokj/nUN2TgG80bfG+MDdbfHKlLcNNba94mbjy2/SXJ1HDgrOkXGAjg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-collapse": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.1.2.tgz",
+ "integrity": "sha512-HujcKq7mghk/gVKeI6EjzTbb8e19XUZpakrYazu1MblEZ3Hu3WBMSN4A3QmvbF6n1g7x6lUlZvsHZ5shABWYOQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.3.4",
+ "rc-util": "^5.2.1",
+ "shallowequal": "^1.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-dialog": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-8.6.0.tgz",
+ "integrity": "sha512-GSbkfqjqxpZC5/zc+8H332+q5l/DKUhpQr0vdX2uDsxo5K0PhvaMEVjyoJUTkZ3+JstEADQji1PVLVb/2bJeOQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-motion": "^2.3.0",
+ "rc-util": "^5.6.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-drawer": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-4.4.3.tgz",
+ "integrity": "sha512-FYztwRs3uXnFOIf1hLvFxIQP9MiZJA+0w+Os8dfDh/90X7z/HqP/Yg+noLCIeHEbKln1Tqelv8ymCAN24zPcfQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.7.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-dropdown": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-3.2.2.tgz",
+ "integrity": "sha512-oA9VYYg+jQaPRdFoYFfBn5EAQk2NlL6H0vR2v6JG/8i4HEfUq8p1TTt6HyQ/dGxLe8lpnK+nM7WCjgZT/cpSRQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-trigger": "^5.0.4"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/antd/node_modules/rc-field-form": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.22.1.tgz",
+ "integrity": "sha512-LweU7nBeqmC5r3HDUjRprcOXXobHXp/TGIxD7ppBq5FX6Iptt3ibdpRVg4RSyNulBNGHOuknHlRcguuIpvVMVg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.8.4",
+ "async-validator": "^4.0.2",
+ "rc-util": "^5.8.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">= 16.9.0",
+ "react-dom": ">= 16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-image": {
+ "version": "5.2.5",
+ "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-5.2.5.tgz",
+ "integrity": "sha512-qUfZjYIODxO0c8a8P5GeuclYXZjzW4hV/5hyo27XqSFo1DmTCs2HkVeQObkcIk5kNsJtgsj1KoPThVsSc/PXOw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.11.2",
+ "classnames": "^2.2.6",
+ "rc-dialog": "~8.6.0",
+ "rc-util": "^5.0.6"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-input-number": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-7.3.4.tgz",
+ "integrity": "sha512-W9uqSzuvJUnz8H8vsVY4kx+yK51SsAxNTwr8SNH4G3XqQNocLVmKIibKFRjocnYX1RDHMND9FFbgj2h7E7nvGA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.9.8"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-mentions": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-1.6.1.tgz",
+ "integrity": "sha512-LDzGI8jJVGnkhpTZxZuYBhMz3avcZZqPGejikchh97xPni/g4ht714Flh7DVvuzHQ+BoKHhIjobHnw1rcP8erg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-menu": "^9.0.0",
+ "rc-textarea": "^0.3.0",
+ "rc-trigger": "^5.0.4",
+ "rc-util": "^5.0.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-menu": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.2.1.tgz",
+ "integrity": "sha512-UbEtn3rflJ8zS+etYGTVQuzy7Fm+yWXR5c0Rl6ecNTS/dPknRyWAyhJcbeR0Hu1+RdQT+0VCqrUPrgKnm4iY+w==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.4.3",
+ "rc-overflow": "^1.2.0",
+ "rc-trigger": "^5.1.2",
+ "rc-util": "^5.12.0",
+ "shallowequal": "^1.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-menu/node_modules/rc-overflow": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.2.2.tgz",
+ "integrity": "sha512-X5kj9LDU1ue5wHkqvCprJWLKC+ZLs3p4He/oxjZ1Q4NKaqKBaYf5OdSzRSgh3WH8kSdrfU8LjvlbWnHgJOEkNQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.5.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-motion": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.4.tgz",
+ "integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.2.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-notification": {
+ "version": "4.5.7",
+ "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-4.5.7.tgz",
+ "integrity": "sha512-zhTGUjBIItbx96SiRu3KVURcLOydLUHZCPpYEn1zvh+re//Tnq/wSxN4FKgp38n4HOgHSVxcLEeSxBMTeBBDdw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.2.0",
+ "rc-util": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-pagination": {
+ "version": "3.1.15",
+ "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-3.1.15.tgz",
+ "integrity": "sha512-4L3fot8g4E+PjWEgoVGX0noFCg+8ZFZmeLH4vsnZpB3O2T2zThtakjNxG+YvSaYtyMVT4B+GLayjKrKbXQpdAg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-picker": {
+ "version": "2.5.19",
+ "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-2.5.19.tgz",
+ "integrity": "sha512-u6myoCu/qiQ0vLbNzSzNrzTQhs7mldArCpPHrEI6OUiifs+IPXmbesqSm0zilJjfzrZJLgYeyyOMSznSlh0GKA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "date-fns": "2.x",
+ "dayjs": "1.x",
+ "moment": "^2.24.0",
+ "rc-trigger": "^5.0.4",
+ "rc-util": "^5.4.0",
+ "shallowequal": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-progress": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.2.4.tgz",
+ "integrity": "sha512-M9WWutRaoVkPUPIrTpRIDpX0SPSrVHzxHdCRCbeoBFrd9UFWTYNWRlHsruJM5FH1AZI+BwB4wOJUNNylg/uFSw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.16.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-rate": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.9.1.tgz",
+ "integrity": "sha512-MmIU7FT8W4LYRRHJD1sgG366qKtSaKb67D0/vVvJYR0lrCuRrCiVQ5qhfT5ghVO4wuVIORGpZs7ZKaYu+KMUzA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-resize-observer": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.2.0.tgz",
+ "integrity": "sha512-6W+UzT3PyDM0wVCEHfoW3qTHPTvbdSgiA43buiy8PzmeMnfgnDeb9NjdimMXMl3/TcrvvWl5RRVdp+NqcR47pQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.15.0",
+ "resize-observer-polyfill": "^1.5.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-select": {
+ "version": "14.0.0-alpha.22",
+ "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.0.0-alpha.22.tgz",
+ "integrity": "sha512-ScNdwUPMgXQbHlk5EisZchrs+HiqdBLzSh/hcjJh2dOA56DhawcZOGn8URS0rJSW4V3IbE26SVYBH60jV56SwQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.0.1",
+ "rc-overflow": "^1.0.0",
+ "rc-trigger": "^5.0.4",
+ "rc-util": "^5.16.1",
+ "rc-virtual-list": "^3.2.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/antd/node_modules/rc-select/node_modules/rc-overflow": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.2.2.tgz",
+ "integrity": "sha512-X5kj9LDU1ue5wHkqvCprJWLKC+ZLs3p4He/oxjZ1Q4NKaqKBaYf5OdSzRSgh3WH8kSdrfU8LjvlbWnHgJOEkNQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.5.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-select/node_modules/rc-virtual-list": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.2.tgz",
+ "integrity": "sha512-OyVrrPvvFcHvV0ssz5EDZ+7Rf5qLat/+mmujjchNw5FfbJWNDwkpQ99EcVE6+FtNRmX9wFa1LGNpZLUTvp/4GQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "classnames": "^2.2.6",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.0.7"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/antd/node_modules/rc-slider": {
+ "version": "9.7.5",
+ "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.5.tgz",
+ "integrity": "sha512-LV/MWcXFjco1epPbdw1JlLXlTgmWpB9/Y/P2yinf8Pg3wElHxA9uajN21lJiWtZjf5SCUekfSP6QMJfDo4t1hg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-tooltip": "^5.0.1",
+ "rc-util": "^5.16.1",
+ "shallowequal": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-steps": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-4.1.4.tgz",
+ "integrity": "sha512-qoCqKZWSpkh/b03ASGx1WhpKnuZcRWmvuW+ZUu4mvMdfvFzVxblTwUM+9aBd0mlEUFmt6GW8FXhMpHkK3Uzp3w==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.2",
+ "classnames": "^2.2.3",
+ "rc-util": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-switch": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-3.2.2.tgz",
+ "integrity": "sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.0.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-table": {
+ "version": "7.22.2",
+ "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.22.2.tgz",
+ "integrity": "sha512-Ng2gNkGi6ybl6dzneRn2H4Gp8XhIbRa5rXQ7ZhZcgWVmfVMok70UHGPXcf68tXW6O0/qckTf/eOVsoviSvK4sw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-resize-observer": "^1.1.0",
+ "rc-util": "^5.14.0",
+ "shallowequal": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-tabs": {
+ "version": "11.10.5",
+ "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-11.10.5.tgz",
+ "integrity": "sha512-DDuUdV6b9zGRYLtjI5hyejWLKoz1QiLWNgMeBzc3aMeQylZFhTYnFGdDc6HRqj5IYearNTsFPVSA+6VIT8g5cg==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.11.2",
+ "classnames": "2.x",
+ "rc-dropdown": "^3.2.0",
+ "rc-menu": "^9.0.0",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.5.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-textarea": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-0.3.7.tgz",
+ "integrity": "sha512-yCdZ6binKmAQB13hc/oehh0E/QRwoPP1pjF21aHBxlgXO3RzPF6dUu4LG2R4FZ1zx/fQd2L1faktulrXOM/2rw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.7.0",
+ "shallowequal": "^1.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-tooltip": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz",
+ "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.11.2",
+ "rc-trigger": "^5.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-tree": {
+ "version": "5.3.8",
+ "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.3.8.tgz",
+ "integrity": "sha512-YuobEryPymqPmHFUOvsoOrYdm24psaj0CrGEUuDUQUeG/nNcTGw6FA2YmF4NsEaNBvNSJUSzwfZnFHrKa/xv0A==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.0.1",
+ "rc-util": "^5.16.1",
+ "rc-virtual-list": "^3.4.1"
+ },
+ "engines": {
+ "node": ">=10.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/antd/node_modules/rc-tree-select": {
+ "version": "5.0.0-alpha.4",
+ "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.0.0-alpha.4.tgz",
+ "integrity": "sha512-jKM8XoN3W/7cQmOP+Ypqcu2b2aa7GS8ZIzbAvdLzHt0h0/pTTuyzsNDpejgrX0+S0D0VkpYaZ1dxJQQ7Tinc1Q==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-select": "~14.0.0-alpha.8",
+ "rc-tree": "~5.3.3",
+ "rc-util": "^5.16.1"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/antd/node_modules/rc-tree/node_modules/rc-virtual-list": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.2.tgz",
+ "integrity": "sha512-OyVrrPvvFcHvV0ssz5EDZ+7Rf5qLat/+mmujjchNw5FfbJWNDwkpQ99EcVE6+FtNRmX9wFa1LGNpZLUTvp/4GQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "classnames": "^2.2.6",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.0.7"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": "*",
+ "react-dom": "*"
+ }
+ },
+ "node_modules/antd/node_modules/rc-trigger": {
+ "version": "5.2.10",
+ "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.10.tgz",
+ "integrity": "sha512-FkUf4H9BOFDaIwu42fvRycXMAvkttph9AlbCZXssZDVzz2L+QZ0ERvfB/4nX3ZFPh1Zd+uVGr1DEDeXxq4J1TA==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.11.2",
+ "classnames": "^2.2.6",
+ "rc-align": "^4.0.0",
+ "rc-motion": "^2.0.0",
+ "rc-util": "^5.5.0"
+ },
+ "engines": {
+ "node": ">=8.x"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-trigger/node_modules/rc-align": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.11.tgz",
+ "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "dom-align": "^1.7.0",
+ "lodash": "^4.17.21",
+ "rc-util": "^5.3.0",
+ "resize-observer-polyfill": "^1.5.1"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-upload": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.3.3.tgz",
+ "integrity": "sha512-YoJ0phCRenMj1nzwalXzciKZ9/FAaCrFu84dS5pphwucTC8GUWClcDID/WWNGsLFcM97NqIboDqrV82rVRhW/w==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.2.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
+ "node_modules/antd/node_modules/rc-util": {
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
+ "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "@babel/runtime": "^7.12.5",
+ "react-is": "^16.12.0",
+ "shallowequal": "^1.1.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.9.0",
+ "react-dom": ">=16.9.0"
+ }
+ },
"node_modules/anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
@@ -1038,6 +2001,25 @@
"integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
"dev": true
},
+ "node_modules/array-move": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/array-move/-/array-move-4.0.0.tgz",
+ "integrity": "sha512-+RY54S8OuVvg94THpneQvFRmqWdAHeqtMzgMW6JNurHxe8rsS07cHQdfGkXnTUXiBcyZ0j3SiDIxxj0RPiqCkQ==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/array-tree-filter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
+ "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -1056,6 +2038,19 @@
"lodash": "^4.17.14"
}
},
+ "node_modules/async-validator": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz",
+ "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==",
+ "dev": true,
+ "peer": true
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
"node_modules/attr-accept": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
@@ -1104,6 +2099,12 @@
"integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
"dev": true
},
+ "node_modules/before-after-hook": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
+ "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==",
+ "dev": true
+ },
"node_modules/big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -1434,6 +2435,15 @@
"node": ">=6"
}
},
+ "node_modules/clsx": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
+ "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/color": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
@@ -1475,6 +2485,18 @@
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
@@ -1536,9 +2558,9 @@
"dev": true
},
"node_modules/compute-scroll-into-view": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.16.tgz",
- "integrity": "sha512-a85LHKY81oQnikatZYA90pufpZ6sQx++BoCxOEMsjpZx+ZnaKGQnCyCehTRr/1p9GBIAHTjcU9k71kSYWloLiQ==",
+ "version": "1.0.17",
+ "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz",
+ "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==",
"dev": true
},
"node_modules/concat-map": {
@@ -1592,6 +2614,16 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
"dev": true
},
+ "node_modules/copy-to-clipboard": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz",
+ "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "toggle-selection": "^1.0.6"
+ }
+ },
"node_modules/core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@@ -1778,6 +2810,13 @@
"url": "https://opencollective.com/date-fns"
}
},
+ "node_modules/dayjs": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
+ "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
@@ -1873,6 +2912,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -1882,6 +2930,12 @@
"node": ">= 0.6"
}
},
+ "node_modules/deprecation": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
+ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
+ "dev": true
+ },
"node_modules/destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
@@ -1960,6 +3014,13 @@
"buffer-indexof": "^1.0.0"
}
},
+ "node_modules/dom-align": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.2.tgz",
+ "integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/dom-converter": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
@@ -2625,6 +3686,20 @@
}
}
},
+ "node_modules/form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -3470,6 +4545,15 @@
"node": ">= 0.10"
}
},
+ "node_modules/invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dev": true,
+ "dependencies": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"node_modules/ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
@@ -3923,11 +5007,21 @@
"dev": true
},
"node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
+ "node_modules/json2mq": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
+ "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "string-convert": "^0.2.0"
+ }
+ },
"node_modules/json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
@@ -4164,6 +5258,13 @@
"node": ">= 4.0.0"
}
},
+ "node_modules/memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/memory-fs": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
@@ -4750,6 +5851,16 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/moment": {
+ "version": "2.29.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
+ "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
+ "dev": true,
+ "peer": true,
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/mrmime": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
@@ -4836,6 +5947,25 @@
"lodash": "^4.17.21"
}
},
+ "node_modules/node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
"node_modules/node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
@@ -5554,22 +6684,22 @@
}
},
"node_modules/postcss-nested": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.5.tgz",
- "integrity": "sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==",
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz",
+ "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==",
"dev": true,
"dependencies": {
- "postcss-selector-parser": "^6.0.4"
+ "postcss-selector-parser": "^6.0.6"
},
"engines": {
- "node": ">=10.0"
+ "node": ">=12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
"peerDependencies": {
- "postcss": "^8.1.13"
+ "postcss": "^8.2.14"
}
},
"node_modules/postcss-selector-parser": {
@@ -5883,6 +7013,35 @@
"react": "^16.8.0 || ^17"
}
},
+ "node_modules/react-sortable-hoc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-2.0.0.tgz",
+ "integrity": "sha512-JZUw7hBsAHXK7PTyErJyI7SopSBFRcFHDjWW5SWjcugY0i6iH7f+eJkY8cJmGMlZ1C9xz1J3Vjz0plFpavVeRg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/runtime": "^7.2.0",
+ "invariant": "^2.2.4",
+ "prop-types": "^15.5.7"
+ },
+ "peerDependencies": {
+ "prop-types": "^15.5.7",
+ "react": "^16.3.0 || ^17.0.0",
+ "react-dom": "^16.3.0 || ^17.0.0"
+ }
+ },
+ "node_modules/react-toastify": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-8.1.0.tgz",
+ "integrity": "sha512-M+Q3rTmEw/53Csr7NsV/YnldJe4c7uERcY7Tma9mvLU98QT2VhIkKwjBzzxZkJRk/oBKyUAtkyMjMgO00hx6gQ==",
+ "dev": true,
+ "dependencies": {
+ "clsx": "^1.1.1"
+ },
+ "peerDependencies": {
+ "react": ">=16",
+ "react-dom": ">=16"
+ }
+ },
"node_modules/read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -6073,6 +7232,13 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
+ "node_modules/resize-observer-polyfill": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/resolve": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
@@ -6204,6 +7370,47 @@
"url": "https://opencollective.com/webpack"
}
},
+ "node_modules/schema-utils/node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/schema-utils/node_modules/ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "peerDependencies": {
+ "ajv": "^6.9.1"
+ }
+ },
+ "node_modules/schema-utils/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ },
+ "node_modules/scroll-into-view-if-needed": {
+ "version": "2.2.28",
+ "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.28.tgz",
+ "integrity": "sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w==",
+ "dev": true,
+ "peer": true,
+ "dependencies": {
+ "compute-scroll-into-view": "^1.0.17"
+ }
+ },
"node_modules/section-matter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz",
@@ -6388,6 +7595,13 @@
"node": ">=8"
}
},
+ "node_modules/shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+ "dev": true,
+ "peer": true
+ },
"node_modules/shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -6606,6 +7820,13 @@
"safe-buffer": "~5.1.0"
}
},
+ "node_modules/string-convert": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
+ "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=",
+ "dev": true,
+ "peer": true
+ },
"node_modules/string.prototype.padend": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz",
@@ -6878,6 +8099,25 @@
"node": ">=10.13.0"
}
},
+ "node_modules/tailwindcss/node_modules/postcss-nested": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.5.tgz",
+ "integrity": "sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==",
+ "dev": true,
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.4"
+ },
+ "engines": {
+ "node": ">=10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ "peerDependencies": {
+ "postcss": "^8.1.13"
+ }
+ },
"node_modules/tailwindcss/node_modules/resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
@@ -7030,6 +8270,13 @@
"node": ">=8.0"
}
},
+ "node_modules/toggle-selection": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
+ "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=",
+ "dev": true,
+ "peer": true
+ },
"node_modules/toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@@ -7048,6 +8295,11 @@
"node": ">=6"
}
},
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
+ },
"node_modules/ts-loader": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.3.tgz",
@@ -7154,9 +8406,9 @@
}
},
"node_modules/typescript": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz",
- "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==",
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
+ "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
"dev": true,
"bin": {
"tsc": "bin/tsc",
@@ -7181,6 +8433,101 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/uniforms": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/uniforms/-/uniforms-3.7.0.tgz",
+ "integrity": "sha512-FnFXckM09QRWqpREJx9xRUeJJgKmToKW4emaKqwVq7/tiospEuEhSr9kE5uxgNwCfTPQBsX5Ymhzx/fMXEDYDQ==",
+ "dev": true,
+ "dependencies": {
+ "invariant": "^2.0.0",
+ "lodash": "^4.0.0",
+ "tslib": "^2.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/vazco/uniforms?sponsor=1"
+ },
+ "peerDependencies": {
+ "react": "^17.0.0 || ^16.8.0"
+ }
+ },
+ "node_modules/uniforms-antd": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/uniforms-antd/-/uniforms-antd-3.7.0.tgz",
+ "integrity": "sha512-eo296J58IVDkZ6YrEeaqPGBoJgZDvPI1Y3ZsqSvgeWjJrI/gOBQ3YwKlKfhDhBeCOE1YvK4aHbF3wtucETFVgg==",
+ "dev": true,
+ "dependencies": {
+ "invariant": "^2.0.0",
+ "lodash": "^4.0.0",
+ "tslib": "^2.2.0",
+ "uniforms": "^3.7.0",
+ "warning": "^4.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/vazco/uniforms?sponsor=1"
+ },
+ "peerDependencies": {
+ "@ant-design/icons": "^4.0.0",
+ "antd": "^4.0.0",
+ "react": "^17.0.0 || ^16.8.0"
+ }
+ },
+ "node_modules/uniforms-antd/node_modules/tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ },
+ "node_modules/uniforms-bridge-json-schema": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/uniforms-bridge-json-schema/-/uniforms-bridge-json-schema-3.7.0.tgz",
+ "integrity": "sha512-VWM0tEwcfYXsXfMicxJXIOi0OQoQDcP+WqwDY/OueJpBy9Nw5nsupuS9uUg6ZUkG0m1aCc3znmsZFQXvAaFdTQ==",
+ "dev": true,
+ "dependencies": {
+ "invariant": "^2.0.0",
+ "lodash": "^4.0.0",
+ "tslib": "^2.2.0",
+ "uniforms": "^3.7.0"
+ },
+ "funding": {
+ "url": "https://github.com/vazco/uniforms?sponsor=1"
+ }
+ },
+ "node_modules/uniforms-bridge-json-schema/node_modules/tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ },
+ "node_modules/uniforms-unstyled": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/uniforms-unstyled/-/uniforms-unstyled-3.7.0.tgz",
+ "integrity": "sha512-FIpYl9aPC39FTJIp9sZbUWu2C8cgvTX1wqRSGHvya2qgcjB0RIQ6/xM11DBD9I6V66fEGhE2sBcrNqL7geB0Zg==",
+ "dev": true,
+ "dependencies": {
+ "invariant": "^2.0.0",
+ "lodash": "^4.0.0",
+ "tslib": "^2.2.0",
+ "uniforms": "^3.7.0"
+ },
+ "funding": {
+ "url": "https://github.com/vazco/uniforms?sponsor=1"
+ },
+ "peerDependencies": {
+ "react": "^17.0.0 || ^16.8.0"
+ }
+ },
+ "node_modules/uniforms-unstyled/node_modules/tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ },
+ "node_modules/uniforms/node_modules/tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ },
"node_modules/unist-util-stringify-position": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz",
@@ -7194,6 +8541,12 @@
"url": "https://opencollective.com/unified"
}
},
+ "node_modules/universal-user-agent": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
+ "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
+ "dev": true
+ },
"node_modules/universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@@ -7340,6 +8693,11 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+ },
"node_modules/webpack": {
"version": "5.65.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz",
@@ -7604,22 +8962,6 @@
}
}
},
- "node_modules/webpack-dev-server/node_modules/ajv": {
- "version": "8.8.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
- "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
- "dev": true,
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
"node_modules/webpack-dev-server/node_modules/ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
@@ -7638,12 +8980,6 @@
"integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==",
"dev": true
},
- "node_modules/webpack-dev-server/node_modules/json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
"node_modules/webpack-dev-server/node_modules/schema-utils": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
@@ -7774,6 +9110,15 @@
"node": ">=0.8.0"
}
},
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"node_modules/which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -7855,6 +9200,51 @@
}
},
"dependencies": {
+ "@ant-design/colors": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-6.0.0.tgz",
+ "integrity": "sha512-qAZRvPzfdWHtfameEGP2Qvuf838NhergR35o+EuVyB5XvSA98xod5r4utvi4TJ3ywmevm290g9nsCG5MryrdWQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@ctrl/tinycolor": "^3.4.0"
+ }
+ },
+ "@ant-design/icons": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-4.7.0.tgz",
+ "integrity": "sha512-aoB4Z7JA431rt6d4u+8xcNPPCrdufSRMUOpxa1ab6mz1JCQZOEVolj2WVs/tDFmN62zzK30mNelEsprLYsSF3g==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@ant-design/colors": "^6.0.0",
+ "@ant-design/icons-svg": "^4.2.1",
+ "@babel/runtime": "^7.11.2",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.9.4"
+ },
+ "dependencies": {
+ "rc-util": {
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
+ "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.12.5",
+ "react-is": "^16.12.0",
+ "shallowequal": "^1.1.0"
+ }
+ }
+ }
+ },
+ "@ant-design/icons-svg": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.2.1.tgz",
+ "integrity": "sha512-EB0iwlKDGpG93hW8f85CTJTs4SvMX7tt5ceupvhALp1IF44SeUFOMhKUOYqpsoYWQKAOuTRDMqn75rEaKDp0Xw==",
+ "dev": true,
+ "peer": true
+ },
"@babel/code-frame": {
"version": "7.10.4",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz",
@@ -7899,6 +9289,13 @@
"lit-element": "^2.5.1"
}
},
+ "@ctrl/tinycolor": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.4.0.tgz",
+ "integrity": "sha512-JZButFdZ1+/xAfpguQHoabIXkcqRRKpMrWKBkpEZZyxfY9C1DpADFB8PEqGSTeFr135SaTRfKqGKx5xSCLI7ZQ==",
+ "dev": true,
+ "peer": true
+ },
"@discoveryjs/json-ext": {
"version": "0.5.6",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.6.tgz",
@@ -7986,6 +9383,26 @@
"ajv": "~6.12.6",
"jju": "~1.4.0",
"resolve": "~1.19.0"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ }
}
},
"@nodelib/fs.scandir": {
@@ -8014,6 +9431,146 @@
"fastq": "^1.6.0"
}
},
+ "@octokit/auth-token": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz",
+ "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==",
+ "dev": true,
+ "requires": {
+ "@octokit/types": "^6.0.3"
+ }
+ },
+ "@octokit/core": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.5.1.tgz",
+ "integrity": "sha512-omncwpLVxMP+GLpLPgeGJBF6IWJFjXDS5flY5VbppePYX9XehevbDykRH9PdCdvqt9TS5AOTiDide7h0qrkHjw==",
+ "dev": true,
+ "requires": {
+ "@octokit/auth-token": "^2.4.4",
+ "@octokit/graphql": "^4.5.8",
+ "@octokit/request": "^5.6.0",
+ "@octokit/request-error": "^2.0.5",
+ "@octokit/types": "^6.0.3",
+ "before-after-hook": "^2.2.0",
+ "universal-user-agent": "^6.0.0"
+ }
+ },
+ "@octokit/endpoint": {
+ "version": "6.0.12",
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz",
+ "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==",
+ "dev": true,
+ "requires": {
+ "@octokit/types": "^6.0.3",
+ "is-plain-object": "^5.0.0",
+ "universal-user-agent": "^6.0.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
+ }
+ },
+ "@octokit/graphql": {
+ "version": "4.8.0",
+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz",
+ "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==",
+ "dev": true,
+ "requires": {
+ "@octokit/request": "^5.6.0",
+ "@octokit/types": "^6.0.3",
+ "universal-user-agent": "^6.0.0"
+ }
+ },
+ "@octokit/openapi-types": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-11.2.0.tgz",
+ "integrity": "sha512-PBsVO+15KSlGmiI8QAzaqvsNlZlrDlyAJYcrXBCvVUxCp7VnXjkwPoFHgjEJXx3WF9BAwkA6nfCUA7i9sODzKA==",
+ "dev": true
+ },
+ "@octokit/plugin-paginate-rest": {
+ "version": "2.17.0",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.17.0.tgz",
+ "integrity": "sha512-tzMbrbnam2Mt4AhuyCHvpRkS0oZ5MvwwcQPYGtMv4tUa5kkzG58SVB0fcsLulOZQeRnOgdkZWkRUiyBlh0Bkyw==",
+ "dev": true,
+ "requires": {
+ "@octokit/types": "^6.34.0"
+ }
+ },
+ "@octokit/plugin-request-log": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz",
+ "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==",
+ "dev": true,
+ "requires": {}
+ },
+ "@octokit/plugin-rest-endpoint-methods": {
+ "version": "5.13.0",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.13.0.tgz",
+ "integrity": "sha512-uJjMTkN1KaOIgNtUPMtIXDOjx6dGYysdIFhgA52x4xSadQCz3b/zJexvITDVpANnfKPW/+E0xkOvLntqMYpviA==",
+ "dev": true,
+ "requires": {
+ "@octokit/types": "^6.34.0",
+ "deprecation": "^2.3.1"
+ }
+ },
+ "@octokit/request": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.2.tgz",
+ "integrity": "sha512-je66CvSEVf0jCpRISxkUcCa0UkxmFs6eGDRSbfJtAVwbLH5ceqF+YEyC8lj8ystKyZTy8adWr0qmkY52EfOeLA==",
+ "dev": true,
+ "requires": {
+ "@octokit/endpoint": "^6.0.1",
+ "@octokit/request-error": "^2.1.0",
+ "@octokit/types": "^6.16.1",
+ "is-plain-object": "^5.0.0",
+ "node-fetch": "^2.6.1",
+ "universal-user-agent": "^6.0.0"
+ },
+ "dependencies": {
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==",
+ "dev": true
+ }
+ }
+ },
+ "@octokit/request-error": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz",
+ "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==",
+ "dev": true,
+ "requires": {
+ "@octokit/types": "^6.0.3",
+ "deprecation": "^2.0.0",
+ "once": "^1.4.0"
+ }
+ },
+ "@octokit/rest": {
+ "version": "18.12.0",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz",
+ "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==",
+ "dev": true,
+ "requires": {
+ "@octokit/core": "^3.5.1",
+ "@octokit/plugin-paginate-rest": "^2.16.8",
+ "@octokit/plugin-request-log": "^1.0.4",
+ "@octokit/plugin-rest-endpoint-methods": "^5.12.0"
+ }
+ },
+ "@octokit/types": {
+ "version": "6.34.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.34.0.tgz",
+ "integrity": "sha512-s1zLBjWhdEI2zwaoSgyOFoKSl109CUcVBCc7biPJ3aAf6LGLU6szDvi31JPU7bxfla2lqfhjbbg/5DdFNxOwHw==",
+ "dev": true,
+ "requires": {
+ "@octokit/openapi-types": "^11.2.0"
+ }
+ },
"@polka/url": {
"version": "1.0.0-next.21",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz",
@@ -8242,6 +9799,16 @@
"integrity": "sha512-Agl6xbYP6FOMDeAsr3QVZ+g7Yzg0uhPHWx0j5g4LFdUBHVtqtU+gH660k/lCEe506jJLOGbEzsnqPDTZGJQLag==",
"dev": true
},
+ "@types/node-fetch": {
+ "version": "2.5.12",
+ "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz",
+ "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "form-data": "^3.0.0"
+ }
+ },
"@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
@@ -8603,14 +10170,14 @@
}
},
"ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "version": "8.8.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
+ "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
"uri-js": "^4.2.2"
}
},
@@ -8621,35 +10188,8 @@
"dev": true,
"requires": {
"ajv": "^8.0.0"
- },
- "dependencies": {
- "ajv": {
- "version": "8.8.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
- "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
- "dev": true,
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- }
- },
- "json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- }
}
},
- "ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "dev": true,
- "requires": {}
- },
"ansi-html-community": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz",
@@ -8671,6 +10211,556 @@
"color-convert": "^1.9.0"
}
},
+ "antd": {
+ "version": "4.18.3",
+ "resolved": "https://registry.npmjs.org/antd/-/antd-4.18.3.tgz",
+ "integrity": "sha512-EoCMY8pFKX9IVAc0Bdi3DWR03IIOHa6mTZALOGjrKbPm3kbrcvoBTCNXq4BMeVA1dZbMeoBw46peeJLyMp2avw==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@ant-design/colors": "^6.0.0",
+ "@ant-design/icons": "^4.7.0",
+ "@ant-design/react-slick": "~0.28.1",
+ "@babel/runtime": "^7.12.5",
+ "@ctrl/tinycolor": "^3.4.0",
+ "array-tree-filter": "^2.1.0",
+ "classnames": "^2.2.6",
+ "copy-to-clipboard": "^3.2.0",
+ "lodash": "^4.17.21",
+ "memoize-one": "^6.0.0",
+ "moment": "^2.25.3",
+ "rc-cascader": "~3.0.0-alpha.3",
+ "rc-checkbox": "~2.3.0",
+ "rc-collapse": "~3.1.0",
+ "rc-dialog": "~8.6.0",
+ "rc-drawer": "~4.4.2",
+ "rc-dropdown": "~3.2.0",
+ "rc-field-form": "~1.22.0-2",
+ "rc-image": "~5.2.5",
+ "rc-input-number": "~7.3.0",
+ "rc-mentions": "~1.6.1",
+ "rc-menu": "~9.2.1",
+ "rc-motion": "^2.4.4",
+ "rc-notification": "~4.5.7",
+ "rc-pagination": "~3.1.9",
+ "rc-picker": "~2.5.17",
+ "rc-progress": "~3.2.1",
+ "rc-rate": "~2.9.0",
+ "rc-resize-observer": "^1.1.2",
+ "rc-select": "~14.0.0-alpha.15",
+ "rc-slider": "~9.7.4",
+ "rc-steps": "~4.1.0",
+ "rc-switch": "~3.2.0",
+ "rc-table": "~7.22.2",
+ "rc-tabs": "~11.10.0",
+ "rc-textarea": "~0.3.0",
+ "rc-tooltip": "~5.1.1",
+ "rc-tree": "~5.3.5",
+ "rc-tree-select": "~5.0.0-alpha.2",
+ "rc-trigger": "^5.2.10",
+ "rc-upload": "~4.3.0",
+ "rc-util": "^5.14.0",
+ "scroll-into-view-if-needed": "^2.2.25"
+ },
+ "dependencies": {
+ "@ant-design/react-slick": {
+ "version": "0.28.4",
+ "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-0.28.4.tgz",
+ "integrity": "sha512-j9eAHTn7GxbXUFNknJoHS2ceAsqrQi2j8XykjZE1IXCD8kJF+t28EvhBLniDpbOsBk/3kjalnhriTfZcjBHNqg==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.4",
+ "classnames": "^2.2.5",
+ "json2mq": "^0.2.0",
+ "lodash": "^4.17.21",
+ "resize-observer-polyfill": "^1.5.0"
+ }
+ },
+ "rc-cascader": {
+ "version": "3.0.0-alpha.7",
+ "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.0.0-alpha.7.tgz",
+ "integrity": "sha512-hHhPJW9ll41vMd36gmZWYem9749KI9cW51tPQWCp/AS98wgdz/m71y0eXzHIsiVrsIq54sAvccmHK/ZwrRi13Q==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.12.5",
+ "array-tree-filter": "^2.1.0",
+ "classnames": "^2.3.1",
+ "rc-select": "~14.0.0-alpha.8",
+ "rc-tree": "~5.3.4",
+ "rc-util": "^5.6.1"
+ }
+ },
+ "rc-checkbox": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-2.3.2.tgz",
+ "integrity": "sha512-afVi1FYiGv1U0JlpNH/UaEXdh6WUJjcWokj/nUN2TgG80bfG+MDdbfHKlLcNNba94mbjy2/SXJ1HDgrOkXGAjg==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1"
+ }
+ },
+ "rc-collapse": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.1.2.tgz",
+ "integrity": "sha512-HujcKq7mghk/gVKeI6EjzTbb8e19XUZpakrYazu1MblEZ3Hu3WBMSN4A3QmvbF6n1g7x6lUlZvsHZ5shABWYOQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.3.4",
+ "rc-util": "^5.2.1",
+ "shallowequal": "^1.1.0"
+ }
+ },
+ "rc-dialog": {
+ "version": "8.6.0",
+ "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-8.6.0.tgz",
+ "integrity": "sha512-GSbkfqjqxpZC5/zc+8H332+q5l/DKUhpQr0vdX2uDsxo5K0PhvaMEVjyoJUTkZ3+JstEADQji1PVLVb/2bJeOQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-motion": "^2.3.0",
+ "rc-util": "^5.6.1"
+ }
+ },
+ "rc-drawer": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-4.4.3.tgz",
+ "integrity": "sha512-FYztwRs3uXnFOIf1hLvFxIQP9MiZJA+0w+Os8dfDh/90X7z/HqP/Yg+noLCIeHEbKln1Tqelv8ymCAN24zPcfQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.7.0"
+ }
+ },
+ "rc-dropdown": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-3.2.2.tgz",
+ "integrity": "sha512-oA9VYYg+jQaPRdFoYFfBn5EAQk2NlL6H0vR2v6JG/8i4HEfUq8p1TTt6HyQ/dGxLe8lpnK+nM7WCjgZT/cpSRQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-trigger": "^5.0.4"
+ }
+ },
+ "rc-field-form": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.22.1.tgz",
+ "integrity": "sha512-LweU7nBeqmC5r3HDUjRprcOXXobHXp/TGIxD7ppBq5FX6Iptt3ibdpRVg4RSyNulBNGHOuknHlRcguuIpvVMVg==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.8.4",
+ "async-validator": "^4.0.2",
+ "rc-util": "^5.8.0"
+ }
+ },
+ "rc-image": {
+ "version": "5.2.5",
+ "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-5.2.5.tgz",
+ "integrity": "sha512-qUfZjYIODxO0c8a8P5GeuclYXZjzW4hV/5hyo27XqSFo1DmTCs2HkVeQObkcIk5kNsJtgsj1KoPThVsSc/PXOw==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.11.2",
+ "classnames": "^2.2.6",
+ "rc-dialog": "~8.6.0",
+ "rc-util": "^5.0.6"
+ }
+ },
+ "rc-input-number": {
+ "version": "7.3.4",
+ "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-7.3.4.tgz",
+ "integrity": "sha512-W9uqSzuvJUnz8H8vsVY4kx+yK51SsAxNTwr8SNH4G3XqQNocLVmKIibKFRjocnYX1RDHMND9FFbgj2h7E7nvGA==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.9.8"
+ }
+ },
+ "rc-mentions": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-1.6.1.tgz",
+ "integrity": "sha512-LDzGI8jJVGnkhpTZxZuYBhMz3avcZZqPGejikchh97xPni/g4ht714Flh7DVvuzHQ+BoKHhIjobHnw1rcP8erg==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-menu": "^9.0.0",
+ "rc-textarea": "^0.3.0",
+ "rc-trigger": "^5.0.4",
+ "rc-util": "^5.0.1"
+ }
+ },
+ "rc-menu": {
+ "version": "9.2.1",
+ "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.2.1.tgz",
+ "integrity": "sha512-UbEtn3rflJ8zS+etYGTVQuzy7Fm+yWXR5c0Rl6ecNTS/dPknRyWAyhJcbeR0Hu1+RdQT+0VCqrUPrgKnm4iY+w==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.4.3",
+ "rc-overflow": "^1.2.0",
+ "rc-trigger": "^5.1.2",
+ "rc-util": "^5.12.0",
+ "shallowequal": "^1.1.0"
+ },
+ "dependencies": {
+ "rc-overflow": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.2.2.tgz",
+ "integrity": "sha512-X5kj9LDU1ue5wHkqvCprJWLKC+ZLs3p4He/oxjZ1Q4NKaqKBaYf5OdSzRSgh3WH8kSdrfU8LjvlbWnHgJOEkNQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.5.1"
+ }
+ }
+ }
+ },
+ "rc-motion": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.4.4.tgz",
+ "integrity": "sha512-ms7n1+/TZQBS0Ydd2Q5P4+wJTSOrhIrwNxLXCZpR7Fa3/oac7Yi803HDALc2hLAKaCTQtw9LmQeB58zcwOsqlQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.2.1"
+ }
+ },
+ "rc-notification": {
+ "version": "4.5.7",
+ "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-4.5.7.tgz",
+ "integrity": "sha512-zhTGUjBIItbx96SiRu3KVURcLOydLUHZCPpYEn1zvh+re//Tnq/wSxN4FKgp38n4HOgHSVxcLEeSxBMTeBBDdw==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.2.0",
+ "rc-util": "^5.0.1"
+ }
+ },
+ "rc-pagination": {
+ "version": "3.1.15",
+ "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-3.1.15.tgz",
+ "integrity": "sha512-4L3fot8g4E+PjWEgoVGX0noFCg+8ZFZmeLH4vsnZpB3O2T2zThtakjNxG+YvSaYtyMVT4B+GLayjKrKbXQpdAg==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1"
+ }
+ },
+ "rc-picker": {
+ "version": "2.5.19",
+ "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-2.5.19.tgz",
+ "integrity": "sha512-u6myoCu/qiQ0vLbNzSzNrzTQhs7mldArCpPHrEI6OUiifs+IPXmbesqSm0zilJjfzrZJLgYeyyOMSznSlh0GKA==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "date-fns": "2.x",
+ "dayjs": "1.x",
+ "moment": "^2.24.0",
+ "rc-trigger": "^5.0.4",
+ "rc-util": "^5.4.0",
+ "shallowequal": "^1.1.0"
+ }
+ },
+ "rc-progress": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.2.4.tgz",
+ "integrity": "sha512-M9WWutRaoVkPUPIrTpRIDpX0SPSrVHzxHdCRCbeoBFrd9UFWTYNWRlHsruJM5FH1AZI+BwB4wOJUNNylg/uFSw==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.6",
+ "rc-util": "^5.16.1"
+ }
+ },
+ "rc-rate": {
+ "version": "2.9.1",
+ "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.9.1.tgz",
+ "integrity": "sha512-MmIU7FT8W4LYRRHJD1sgG366qKtSaKb67D0/vVvJYR0lrCuRrCiVQ5qhfT5ghVO4wuVIORGpZs7ZKaYu+KMUzA==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.0.1"
+ }
+ },
+ "rc-resize-observer": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.2.0.tgz",
+ "integrity": "sha512-6W+UzT3PyDM0wVCEHfoW3qTHPTvbdSgiA43buiy8PzmeMnfgnDeb9NjdimMXMl3/TcrvvWl5RRVdp+NqcR47pQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.15.0",
+ "resize-observer-polyfill": "^1.5.1"
+ }
+ },
+ "rc-select": {
+ "version": "14.0.0-alpha.22",
+ "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.0.0-alpha.22.tgz",
+ "integrity": "sha512-ScNdwUPMgXQbHlk5EisZchrs+HiqdBLzSh/hcjJh2dOA56DhawcZOGn8URS0rJSW4V3IbE26SVYBH60jV56SwQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.0.1",
+ "rc-overflow": "^1.0.0",
+ "rc-trigger": "^5.0.4",
+ "rc-util": "^5.16.1",
+ "rc-virtual-list": "^3.2.0"
+ },
+ "dependencies": {
+ "rc-overflow": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.2.2.tgz",
+ "integrity": "sha512-X5kj9LDU1ue5wHkqvCprJWLKC+ZLs3p4He/oxjZ1Q4NKaqKBaYf5OdSzRSgh3WH8kSdrfU8LjvlbWnHgJOEkNQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.11.1",
+ "classnames": "^2.2.1",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.5.1"
+ }
+ },
+ "rc-virtual-list": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.2.tgz",
+ "integrity": "sha512-OyVrrPvvFcHvV0ssz5EDZ+7Rf5qLat/+mmujjchNw5FfbJWNDwkpQ99EcVE6+FtNRmX9wFa1LGNpZLUTvp/4GQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "classnames": "^2.2.6",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.0.7"
+ }
+ }
+ }
+ },
+ "rc-slider": {
+ "version": "9.7.5",
+ "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-9.7.5.tgz",
+ "integrity": "sha512-LV/MWcXFjco1epPbdw1JlLXlTgmWpB9/Y/P2yinf8Pg3wElHxA9uajN21lJiWtZjf5SCUekfSP6QMJfDo4t1hg==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-tooltip": "^5.0.1",
+ "rc-util": "^5.16.1",
+ "shallowequal": "^1.1.0"
+ }
+ },
+ "rc-steps": {
+ "version": "4.1.4",
+ "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-4.1.4.tgz",
+ "integrity": "sha512-qoCqKZWSpkh/b03ASGx1WhpKnuZcRWmvuW+ZUu4mvMdfvFzVxblTwUM+9aBd0mlEUFmt6GW8FXhMpHkK3Uzp3w==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.2",
+ "classnames": "^2.2.3",
+ "rc-util": "^5.0.1"
+ }
+ },
+ "rc-switch": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-3.2.2.tgz",
+ "integrity": "sha512-+gUJClsZZzvAHGy1vZfnwySxj+MjLlGRyXKXScrtCTcmiYNPzxDFOxdQ/3pK1Kt/0POvwJ/6ALOR8gwdXGhs+A==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "rc-util": "^5.0.1"
+ }
+ },
+ "rc-table": {
+ "version": "7.22.2",
+ "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.22.2.tgz",
+ "integrity": "sha512-Ng2gNkGi6ybl6dzneRn2H4Gp8XhIbRa5rXQ7ZhZcgWVmfVMok70UHGPXcf68tXW6O0/qckTf/eOVsoviSvK4sw==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-resize-observer": "^1.1.0",
+ "rc-util": "^5.14.0",
+ "shallowequal": "^1.1.0"
+ }
+ },
+ "rc-tabs": {
+ "version": "11.10.5",
+ "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-11.10.5.tgz",
+ "integrity": "sha512-DDuUdV6b9zGRYLtjI5hyejWLKoz1QiLWNgMeBzc3aMeQylZFhTYnFGdDc6HRqj5IYearNTsFPVSA+6VIT8g5cg==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.11.2",
+ "classnames": "2.x",
+ "rc-dropdown": "^3.2.0",
+ "rc-menu": "^9.0.0",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.5.0"
+ }
+ },
+ "rc-textarea": {
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-0.3.7.tgz",
+ "integrity": "sha512-yCdZ6binKmAQB13hc/oehh0E/QRwoPP1pjF21aHBxlgXO3RzPF6dUu4LG2R4FZ1zx/fQd2L1faktulrXOM/2rw==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.1",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.7.0",
+ "shallowequal": "^1.1.0"
+ }
+ },
+ "rc-tooltip": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-5.1.1.tgz",
+ "integrity": "sha512-alt8eGMJulio6+4/uDm7nvV+rJq9bsfxFDCI0ljPdbuoygUscbsMYb6EQgwib/uqsXQUvzk+S7A59uYHmEgmDA==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.11.2",
+ "rc-trigger": "^5.0.0"
+ }
+ },
+ "rc-tree": {
+ "version": "5.3.8",
+ "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.3.8.tgz",
+ "integrity": "sha512-YuobEryPymqPmHFUOvsoOrYdm24psaj0CrGEUuDUQUeG/nNcTGw6FA2YmF4NsEaNBvNSJUSzwfZnFHrKa/xv0A==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-motion": "^2.0.1",
+ "rc-util": "^5.16.1",
+ "rc-virtual-list": "^3.4.1"
+ },
+ "dependencies": {
+ "rc-virtual-list": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.4.2.tgz",
+ "integrity": "sha512-OyVrrPvvFcHvV0ssz5EDZ+7Rf5qLat/+mmujjchNw5FfbJWNDwkpQ99EcVE6+FtNRmX9wFa1LGNpZLUTvp/4GQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "classnames": "^2.2.6",
+ "rc-resize-observer": "^1.0.0",
+ "rc-util": "^5.0.7"
+ }
+ }
+ }
+ },
+ "rc-tree-select": {
+ "version": "5.0.0-alpha.4",
+ "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.0.0-alpha.4.tgz",
+ "integrity": "sha512-jKM8XoN3W/7cQmOP+Ypqcu2b2aa7GS8ZIzbAvdLzHt0h0/pTTuyzsNDpejgrX0+S0D0VkpYaZ1dxJQQ7Tinc1Q==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "rc-select": "~14.0.0-alpha.8",
+ "rc-tree": "~5.3.3",
+ "rc-util": "^5.16.1"
+ }
+ },
+ "rc-trigger": {
+ "version": "5.2.10",
+ "resolved": "https://registry.npmjs.org/rc-trigger/-/rc-trigger-5.2.10.tgz",
+ "integrity": "sha512-FkUf4H9BOFDaIwu42fvRycXMAvkttph9AlbCZXssZDVzz2L+QZ0ERvfB/4nX3ZFPh1Zd+uVGr1DEDeXxq4J1TA==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.11.2",
+ "classnames": "^2.2.6",
+ "rc-align": "^4.0.0",
+ "rc-motion": "^2.0.0",
+ "rc-util": "^5.5.0"
+ },
+ "dependencies": {
+ "rc-align": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/rc-align/-/rc-align-4.0.11.tgz",
+ "integrity": "sha512-n9mQfIYQbbNTbefyQnRHZPWuTEwG1rY4a9yKlIWHSTbgwI+XUMGRYd0uJ5pE2UbrNX0WvnMBA1zJ3Lrecpra/A==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "2.x",
+ "dom-align": "^1.7.0",
+ "lodash": "^4.17.21",
+ "rc-util": "^5.3.0",
+ "resize-observer-polyfill": "^1.5.1"
+ }
+ }
+ }
+ },
+ "rc-upload": {
+ "version": "4.3.3",
+ "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.3.3.tgz",
+ "integrity": "sha512-YoJ0phCRenMj1nzwalXzciKZ9/FAaCrFu84dS5pphwucTC8GUWClcDID/WWNGsLFcM97NqIboDqrV82rVRhW/w==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.10.1",
+ "classnames": "^2.2.5",
+ "rc-util": "^5.2.0"
+ }
+ },
+ "rc-util": {
+ "version": "5.16.1",
+ "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.16.1.tgz",
+ "integrity": "sha512-kSCyytvdb3aRxQacS/71ta6c+kBWvM1v8/2h9d/HaNWauc3qB8pLnF20PJ8NajkNN8gb+rR1l0eWO+D4Pz+LLQ==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "@babel/runtime": "^7.12.5",
+ "react-is": "^16.12.0",
+ "shallowequal": "^1.1.0"
+ }
+ }
+ }
+ },
"anymatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz",
@@ -8702,6 +10792,19 @@
"integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==",
"dev": true
},
+ "array-move": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/array-move/-/array-move-4.0.0.tgz",
+ "integrity": "sha512-+RY54S8OuVvg94THpneQvFRmqWdAHeqtMzgMW6JNurHxe8rsS07cHQdfGkXnTUXiBcyZ0j3SiDIxxj0RPiqCkQ==",
+ "dev": true
+ },
+ "array-tree-filter": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz",
+ "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==",
+ "dev": true,
+ "peer": true
+ },
"array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -8717,6 +10820,19 @@
"lodash": "^4.17.14"
}
},
+ "async-validator": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz",
+ "integrity": "sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==",
+ "dev": true,
+ "peer": true
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
"attr-accept": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-2.2.2.tgz",
@@ -8749,6 +10865,12 @@
"integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=",
"dev": true
},
+ "before-after-hook": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.2.tgz",
+ "integrity": "sha512-3pZEU3NT5BFUo/AD5ERPWOgQOCZITni6iavr5AUw5AUwQjMlI0kzu5btnyD39AF0gUEsDPwJT+oY1ORBJijPjQ==",
+ "dev": true
+ },
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
@@ -9007,6 +11129,12 @@
"shallow-clone": "^3.0.0"
}
},
+ "clsx": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz",
+ "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==",
+ "dev": true
+ },
"color": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
@@ -9048,6 +11176,15 @@
"integrity": "sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w==",
"dev": true
},
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
"commander": {
"version": "2.20.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
@@ -9102,9 +11239,9 @@
}
},
"compute-scroll-into-view": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.16.tgz",
- "integrity": "sha512-a85LHKY81oQnikatZYA90pufpZ6sQx++BoCxOEMsjpZx+ZnaKGQnCyCehTRr/1p9GBIAHTjcU9k71kSYWloLiQ==",
+ "version": "1.0.17",
+ "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz",
+ "integrity": "sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg==",
"dev": true
},
"concat-map": {
@@ -9146,6 +11283,16 @@
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
"dev": true
},
+ "copy-to-clipboard": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz",
+ "integrity": "sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "toggle-selection": "^1.0.6"
+ }
+ },
"core-util-is": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
@@ -9284,6 +11431,13 @@
"integrity": "sha512-5ycpauovVyAk0kXNZz6ZoB9AYMZB4DObse7P3BPWmyEjXNORTI8EJ6X0uaSAq4sCHzM1uajzrkr6HnsLQpxGXA==",
"dev": true
},
+ "dayjs": {
+ "version": "1.10.7",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.7.tgz",
+ "integrity": "sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==",
+ "dev": true,
+ "peer": true
+ },
"debug": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz",
@@ -9353,12 +11507,24 @@
"slash": "^3.0.0"
}
},
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
"dev": true
},
+ "deprecation": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
+ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
+ "dev": true
+ },
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
@@ -9428,6 +11594,13 @@
"buffer-indexof": "^1.0.0"
}
},
+ "dom-align": {
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/dom-align/-/dom-align-1.12.2.tgz",
+ "integrity": "sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==",
+ "dev": true,
+ "peer": true
+ },
"dom-converter": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz",
@@ -9968,6 +12141,17 @@
"integrity": "sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==",
"dev": true
},
+ "form-data": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
+ "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ },
"forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -10604,6 +12788,15 @@
"integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==",
"dev": true
},
+ "invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
@@ -10914,11 +13107,21 @@
"dev": true
},
"json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"dev": true
},
+ "json2mq": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz",
+ "integrity": "sha1-tje9O6nqvhIsg+lyBIOusQ0skEo=",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "string-convert": "^0.2.0"
+ }
+ },
"json5": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
@@ -11113,6 +13316,13 @@
"fs-monkey": "1.0.3"
}
},
+ "memoize-one": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
+ "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
+ "dev": true,
+ "peer": true
+ },
"memory-fs": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz",
@@ -11456,6 +13666,13 @@
"integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==",
"dev": true
},
+ "moment": {
+ "version": "2.29.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
+ "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==",
+ "dev": true,
+ "peer": true
+ },
"mrmime": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz",
@@ -11527,6 +13744,14 @@
"lodash": "^4.17.21"
}
},
+ "node-fetch": {
+ "version": "2.6.7",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
+ "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
+ "requires": {
+ "whatwg-url": "^5.0.0"
+ }
+ },
"node-forge": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
@@ -12039,12 +14264,12 @@
}
},
"postcss-nested": {
- "version": "5.0.5",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.5.tgz",
- "integrity": "sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==",
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.6.tgz",
+ "integrity": "sha512-rKqm2Fk0KbA8Vt3AdGN0FB9OBOMDVajMG6ZCf/GoHgdxUJ4sBFp0A/uMIRm+MJUdo33YXEtjqIz8u7DAp8B7DA==",
"dev": true,
"requires": {
- "postcss-selector-parser": "^6.0.4"
+ "postcss-selector-parser": "^6.0.6"
}
},
"postcss-selector-parser": {
@@ -12281,6 +14506,26 @@
"warning": "^4.0.2"
}
},
+ "react-sortable-hoc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/react-sortable-hoc/-/react-sortable-hoc-2.0.0.tgz",
+ "integrity": "sha512-JZUw7hBsAHXK7PTyErJyI7SopSBFRcFHDjWW5SWjcugY0i6iH7f+eJkY8cJmGMlZ1C9xz1J3Vjz0plFpavVeRg==",
+ "dev": true,
+ "requires": {
+ "@babel/runtime": "^7.2.0",
+ "invariant": "^2.2.4",
+ "prop-types": "^15.5.7"
+ }
+ },
+ "react-toastify": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-8.1.0.tgz",
+ "integrity": "sha512-M+Q3rTmEw/53Csr7NsV/YnldJe4c7uERcY7Tma9mvLU98QT2VhIkKwjBzzxZkJRk/oBKyUAtkyMjMgO00hx6gQ==",
+ "dev": true,
+ "requires": {
+ "clsx": "^1.1.1"
+ }
+ },
"read-pkg": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@@ -12433,6 +14678,13 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
"dev": true
},
+ "resize-observer-polyfill": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
+ "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==",
+ "dev": true,
+ "peer": true
+ },
"resolve": {
"version": "1.19.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz",
@@ -12519,6 +14771,43 @@
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ajv-keywords": {
+ "version": "3.5.2",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
+ "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
+ "dev": true,
+ "requires": {}
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true
+ }
+ }
+ },
+ "scroll-into-view-if-needed": {
+ "version": "2.2.28",
+ "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.28.tgz",
+ "integrity": "sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w==",
+ "dev": true,
+ "peer": true,
+ "requires": {
+ "compute-scroll-into-view": "^1.0.17"
}
},
"section-matter": {
@@ -12690,6 +14979,13 @@
"kind-of": "^6.0.2"
}
},
+ "shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==",
+ "dev": true,
+ "peer": true
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -12880,6 +15176,13 @@
"safe-buffer": "~5.1.0"
}
},
+ "string-convert": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz",
+ "integrity": "sha1-aYLMMEn7tM2F+LJFaLnZvznu/5c=",
+ "dev": true,
+ "peer": true
+ },
"string.prototype.padend": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz",
@@ -13075,6 +15378,15 @@
"is-glob": "^4.0.1"
}
},
+ "postcss-nested": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-5.0.5.tgz",
+ "integrity": "sha512-GSRXYz5bccobpTzLQZXOnSOfKl6TwVr5CyAQJUPub4nuRJSOECK5AqurxVgmtxP48p0Kc/ndY/YyS1yqldX0Ew==",
+ "dev": true,
+ "requires": {
+ "postcss-selector-parser": "^6.0.4"
+ }
+ },
"resolve": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
@@ -13173,6 +15485,13 @@
"is-number": "^7.0.0"
}
},
+ "toggle-selection": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
+ "integrity": "sha1-bkWxJj8gF/oKzH2J14sVuL932jI=",
+ "dev": true,
+ "peer": true
+ },
"toidentifier": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
@@ -13185,6 +15504,11 @@
"integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==",
"dev": true
},
+ "tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
+ },
"ts-loader": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.3.tgz",
@@ -13267,9 +15591,9 @@
}
},
"typescript": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz",
- "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==",
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz",
+ "integrity": "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==",
"dev": true
},
"unbox-primitive": {
@@ -13284,6 +15608,86 @@
"which-boxed-primitive": "^1.0.2"
}
},
+ "uniforms": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/uniforms/-/uniforms-3.7.0.tgz",
+ "integrity": "sha512-FnFXckM09QRWqpREJx9xRUeJJgKmToKW4emaKqwVq7/tiospEuEhSr9kE5uxgNwCfTPQBsX5Ymhzx/fMXEDYDQ==",
+ "dev": true,
+ "requires": {
+ "invariant": "^2.0.0",
+ "lodash": "^4.0.0",
+ "tslib": "^2.2.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ }
+ }
+ },
+ "uniforms-antd": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/uniforms-antd/-/uniforms-antd-3.7.0.tgz",
+ "integrity": "sha512-eo296J58IVDkZ6YrEeaqPGBoJgZDvPI1Y3ZsqSvgeWjJrI/gOBQ3YwKlKfhDhBeCOE1YvK4aHbF3wtucETFVgg==",
+ "dev": true,
+ "requires": {
+ "invariant": "^2.0.0",
+ "lodash": "^4.0.0",
+ "tslib": "^2.2.0",
+ "uniforms": "^3.7.0",
+ "warning": "^4.0.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ }
+ }
+ },
+ "uniforms-bridge-json-schema": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/uniforms-bridge-json-schema/-/uniforms-bridge-json-schema-3.7.0.tgz",
+ "integrity": "sha512-VWM0tEwcfYXsXfMicxJXIOi0OQoQDcP+WqwDY/OueJpBy9Nw5nsupuS9uUg6ZUkG0m1aCc3znmsZFQXvAaFdTQ==",
+ "dev": true,
+ "requires": {
+ "invariant": "^2.0.0",
+ "lodash": "^4.0.0",
+ "tslib": "^2.2.0",
+ "uniforms": "^3.7.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ }
+ }
+ },
+ "uniforms-unstyled": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/uniforms-unstyled/-/uniforms-unstyled-3.7.0.tgz",
+ "integrity": "sha512-FIpYl9aPC39FTJIp9sZbUWu2C8cgvTX1wqRSGHvya2qgcjB0RIQ6/xM11DBD9I6V66fEGhE2sBcrNqL7geB0Zg==",
+ "dev": true,
+ "requires": {
+ "invariant": "^2.0.0",
+ "lodash": "^4.0.0",
+ "tslib": "^2.2.0",
+ "uniforms": "^3.7.0"
+ },
+ "dependencies": {
+ "tslib": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz",
+ "integrity": "sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==",
+ "dev": true
+ }
+ }
+ },
"unist-util-stringify-position": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.0.tgz",
@@ -13293,6 +15697,12 @@
"@types/unist": "^2.0.0"
}
},
+ "universal-user-agent": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz",
+ "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==",
+ "dev": true
+ },
"universalify": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
@@ -13422,6 +15832,11 @@
"dev": true,
"from": "wc-react@github:estruyf/wc-react"
},
+ "webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
+ },
"webpack": {
"version": "5.65.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.65.0.tgz",
@@ -13620,18 +16035,6 @@
"ws": "^8.1.0"
},
"dependencies": {
- "ajv": {
- "version": "8.8.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.8.2.tgz",
- "integrity": "sha512-x9VuX+R/jcFj1DHo/fCp99esgGDWiHENrKxaCENuCxpoMCmAt/COCGVDwA7kleEpEzJjDnvh3yGoOuLu0Dtllw==",
- "dev": true,
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.2.2"
- }
- },
"ajv-keywords": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
@@ -13647,12 +16050,6 @@
"integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==",
"dev": true
},
- "json-schema-traverse": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
- "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
- "dev": true
- },
"schema-utils": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz",
@@ -13720,6 +16117,15 @@
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==",
"dev": true
},
+ "whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=",
+ "requires": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
diff --git a/package.json b/package.json
index 5da18629..17232b2e 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
"displayName": "Front Matter",
"description": "Front Matter is a CMS that runs within Visual Studio Code. It gives you the power and control of a full-blown CMS while also providing you the flexibility and speed of the static site generator of your choice like: Hugo, Jekyll, Hexo, NextJs, Gatsby, and many more...",
"icon": "assets/frontmatter-teal-128x128.png",
- "version": "5.10.0",
+ "version": "6.0.0",
"preview": false,
"publisher": "eliostruyf",
"galleryBanner": {
@@ -100,9 +100,16 @@
"frontMatter.content.defaultFileType": {
"type": "string",
"default": "md",
- "enum": [
- "md",
- "mdx"
+ "oneOf": [
+ {
+ "enum": [
+ "md",
+ "mdx"
+ ]
+ },
+ {
+ "type": "string"
+ }
],
"markdownDescription": "Specify the default file type for the content to create. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.content.defaultfiletype)",
"scope": "Content"
@@ -198,6 +205,30 @@
},
"scope": "Content"
},
+ "frontMatter.content.placeholders": {
+ "type": "array",
+ "default": [],
+ "markdownDescription": "This array of placeholders defines the placeholders that you can use in your content types and templates for automatically populating your content its front matter. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.content.placeholders)",
+ "items": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "ID of the placeholder, in your content type or template, use it as follows: {{placeholder}}"
+ },
+ "value": {
+ "type": "string",
+ "description": "The placeholder its value"
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "value"
+ ]
+ },
+ "scope": "Content"
+ },
"frontMatter.content.publicFolder": {
"type": "string",
"default": "",
@@ -250,6 +281,19 @@
},
"scope": "Content"
},
+ "frontMatter.content.supportedFileTypes": {
+ "type": "array",
+ "default": [
+ "md",
+ "mdx",
+ "markdown"
+ ],
+ "markdownDescription": "Specify the file types that you want to use in Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.content.supportedfiletypes)",
+ "items": {
+ "type": "string"
+ },
+ "scope": "Content"
+ },
"frontMatter.content.wysiwyg": {
"type": "boolean",
"default": true,
@@ -329,11 +373,181 @@
"markdownDescription": "Specify if you want to open the dashboard when you start VS Code. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.dashboard.openonstart)",
"scope": "Dashboard"
},
+ "frontMatter.data.files": {
+ "type": "array",
+ "default": [],
+ "markdownDescription": "Specify the data files you want to use for your website. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.data.files)",
+ "items": {
+ "type": "object",
+ "default": {},
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Your unique ID you want to use for your data file."
+ },
+ "title": {
+ "type": "string",
+ "description": "Title you want to give to your data file."
+ },
+ "labelField": {
+ "type": "string",
+ "description": "The field you want to use as label for your data entries."
+ },
+ "file": {
+ "type": "string",
+ "description": "Path to the file to load. Only JSON or YAML files are supported."
+ },
+ "fileType": {
+ "type": "string",
+ "default": "json",
+ "enum": [
+ "json",
+ "yaml"
+ ],
+ "description": "Defines how you want to parse the file. JSON is the default."
+ },
+ "schema": {
+ "type": "object",
+ "default": {},
+ "description": "The JSON schema for your data which will be used to render the data form.",
+ "additionalProperties": true
+ },
+ "type": {
+ "type": "string",
+ "default": "content",
+ "description": "If you are using data types, you can specify your type ID."
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "title",
+ "file"
+ ],
+ "anyOf": [
+ {
+ "required": [
+ "schema"
+ ]
+ },
+ {
+ "required": [
+ "type"
+ ]
+ }
+ ]
+ },
+ "scope": "Data"
+ },
+ "frontMatter.data.folders": {
+ "type": "array",
+ "default": [],
+ "markdownDescription": "Specify the data files you want to use for your website. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.data.files)",
+ "items": {
+ "type": "object",
+ "default": {},
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Your unique ID you want to use for your data folder."
+ },
+ "labelField": {
+ "type": "string",
+ "description": "The field you want to use as label for your data entries."
+ },
+ "path": {
+ "type": "string",
+ "description": "Path to the folder to load files."
+ },
+ "schema": {
+ "type": "object",
+ "default": {},
+ "description": "The JSON schema for your data which will be used to render the data form.",
+ "additionalProperties": true
+ },
+ "type": {
+ "type": "string",
+ "default": "content",
+ "description": "If you are using data types, you can specify your type ID."
+ }
+ },
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "path"
+ ],
+ "anyOf": [
+ {
+ "required": [
+ "schema"
+ ]
+ },
+ {
+ "required": [
+ "type"
+ ]
+ }
+ ]
+ },
+ "scope": "Data"
+ },
+ "frontMatter.data.types": {
+ "type": "array",
+ "default": [],
+ "markdownDescription": "Specify the data types. These types can be used in for your data files. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.data.types)",
+ "items": {
+ "type": "object",
+ "default": {},
+ "properties": {
+ "id": {
+ "type": "string",
+ "description": "Your unique ID you want to use for your data type."
+ },
+ "schema": {
+ "type": "object",
+ "default": {},
+ "description": "The JSON schema for your data which will be used to render the data form.",
+ "additionalProperties": true
+ }
+ },
+ "required": [
+ "id",
+ "schema"
+ ]
+ },
+ "scope": "Data"
+ },
"frontMatter.framework.id": {
"type": "string",
"default": "",
"markdownDescription": "Specify the ID of your static site generator or framework you are using for your website. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.framework.id)"
},
+ "frontMatter.framework.startCommand": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "default": null,
+ "markdownDescription": "Specify the command you want to use to start your static site generator or framework. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.framework.startcommand)"
+ },
+ "frontMatter.global.notifications": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "info",
+ "warning",
+ "error"
+ ]
+ },
+ "default": [
+ "info",
+ "warning",
+ "error"
+ ],
+ "markdownDescription": "Specifies the notifications you want to see. By default, all notifications types will be shown. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.global.notifications)",
+ "scope": "Templates"
+ },
"frontMatter.media.defaultSorting": {
"type": "string",
"default": "",
@@ -417,6 +631,7 @@
"description": "Specifies the type of content you want to create."
},
"fields": {
+ "$id": "#contenttypefield",
"type": "array",
"description": "Define the fields of the content type",
"items": {
@@ -435,7 +650,8 @@
"taxonomy",
"tags",
"categories",
- "draft"
+ "draft",
+ "fields"
],
"description": "Define the type of field"
},
@@ -447,6 +663,10 @@
"type": "string",
"description": "Title to show in the UI"
},
+ "default": {
+ "type": "string",
+ "description": "Default value"
+ },
"choices": {
"type": "array",
"description": "Define your choices",
@@ -494,6 +714,9 @@
"type": "string",
"default": "",
"description": "The ID of your taxonomy field"
+ },
+ "fields": {
+ "$ref": "#contenttypefield"
}
},
"additionalProperties": false,
@@ -529,6 +752,20 @@
"choices"
]
}
+ },
+ {
+ "if": {
+ "properties": {
+ "type": {
+ "const": "fields"
+ }
+ }
+ },
+ "then": {
+ "required": [
+ "fields"
+ ]
+ }
}
]
}
@@ -639,12 +876,14 @@
"default": "YAML",
"enum": [
"YAML",
- "TOML"
+ "TOML",
+ "JSON"
],
"markdownDescription": "Specify the type of Front Matter to use. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.taxonomy.frontmattertype)",
"enumDescriptions": [
"Specifies you want to use YAML markup for the front matter (default)",
- "Specifies you want to use TOML markup for the front matter"
+ "Specifies you want to use TOML markup for the front matter",
+ "Specifies you want to use JSON markup for the front matter"
],
"scope": "Taxonomy"
},
@@ -728,148 +967,13 @@
"default": "yyyy-MM-dd",
"markdownDescription": "Specify the prefix you want to add for your new article filenames. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.templates.prefix)",
"scope": "Templates"
- },
- "frontMatter.global.notifications": {
- "type": "array",
- "items": {
- "type": "string",
- "enum": [
- "info",
- "warning",
- "error"
- ]
- },
- "default": [
- "info",
- "warning",
- "error"
- ],
- "markdownDescription": "Specifies the notifications you want to see. By default, all notifications types will be shown. [Check in the docs](https://frontmatter.codes/docs/settings#frontmatter.global.notifications)",
- "scope": "Templates"
}
}
},
"commands": [
{
- "command": "frontMatter.collapseSections",
- "title": "Collapse sections",
- "category": "Front matter",
- "icon": {
- "light": "assets/icons/close-light.svg",
- "dark": "assets/icons/close-dark.svg"
- }
- },
- {
- "command": "frontMatter.createTemplate",
- "title": "Create a template from current file",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.createCategory",
- "title": "Create category",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.createTag",
- "title": "Create tag",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.exportTaxonomy",
- "title": "Export all tags & categories to your settings",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.createFromTemplate",
- "title": "Front Matter: New article from template"
- },
- {
- "command": "frontMatter.registerFolder",
- "title": "Front Matter: Register folder"
- },
- {
- "command": "frontMatter.unregisterFolder",
- "title": "Front Matter: Unregister folder"
- },
- {
- "command": "frontMatter.generateSlug",
- "title": "Generate slug based on content title",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.init",
- "title": "Initialize project",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.insertCategories",
- "title": "Insert categories",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.insertImage",
- "title": "Insert image into your content",
- "category": "Front matter",
- "icon": {
- "dark": "/assets/icons/media-dark.svg",
- "light": "/assets/icons/media-light.svg"
- }
- },
- {
- "command": "frontMatter.insertTags",
- "title": "Insert tags",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.createContent",
- "title": "Create new content from defined content type or template",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.dashboard",
- "title": "Open dashboard",
- "category": "Front matter",
- "icon": {
- "dark": "/assets/icons/frontmatter-small-dark.svg",
- "light": "/assets/icons/frontmatter-small-light.svg"
- }
- },
- {
- "command": "frontMatter.dashboard.media",
- "title": "Open media dashboard",
- "category": "Front matter",
- "icon": {
- "dark": "/assets/icons/frontmatter-small-dark.svg",
- "light": "/assets/icons/frontmatter-small-light.svg"
- }
- },
- {
- "command": "frontMatter.dashboard.close",
- "title": "Close dashboard",
- "category": "Front matter",
- "icon": {
- "dark": "/assets/icons/frontmatter-small-teal.svg",
- "light": "/assets/icons/frontmatter-small-teal.svg"
- }
- },
- {
- "command": "frontMatter.preview",
- "title": "Preview content",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.promoteSettings",
- "title": "Promote settings from local to team level",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.remap",
- "title": "Remap or remove tag/category in all articles",
- "category": "Front matter"
- },
- {
- "command": "frontMatter.setLastModifiedDate",
- "title": "Set lastmod date",
+ "command": "frontMatter.authenticate",
+ "title": "Authenticate",
"category": "Front matter"
},
{
@@ -882,21 +986,12 @@
}
},
{
- "command": "frontMatter.markup.italic",
- "title": "Italic",
+ "command": "frontMatter.dashboard.close",
+ "title": "Close dashboard",
"category": "Front matter",
"icon": {
- "light": "assets/icons/italic-light.svg",
- "dark": "assets/icons/italic-dark.svg"
- }
- },
- {
- "command": "frontMatter.markup.strikethrough",
- "title": "Strikethrough",
- "category": "Front matter",
- "icon": {
- "light": "assets/icons/strikethrough-light.svg",
- "dark": "assets/icons/strikethrough-dark.svg"
+ "dark": "/assets/icons/frontmatter-small-teal.svg",
+ "light": "/assets/icons/frontmatter-small-teal.svg"
}
},
{
@@ -926,6 +1021,62 @@
"dark": "assets/icons/blockquote-dark.svg"
}
},
+ {
+ "command": "frontMatter.collapseSections",
+ "title": "Collapse sections",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/close-light.svg",
+ "dark": "assets/icons/close-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.createTemplate",
+ "title": "Create a template from current file",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.createCategory",
+ "title": "Create category",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.createContent",
+ "title": "Create new content from defined content type or template",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.createTag",
+ "title": "Create tag",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.diagnostics",
+ "title": "Diagnostic logging",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.exportTaxonomy",
+ "title": "Export all tags & categories to your settings",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.createFromTemplate",
+ "title": "Front Matter: New article from template"
+ },
+ {
+ "command": "frontMatter.registerFolder",
+ "title": "Front Matter: Register folder"
+ },
+ {
+ "command": "frontMatter.unregisterFolder",
+ "title": "Front Matter: Unregister folder"
+ },
+ {
+ "command": "frontMatter.generateSlug",
+ "title": "Generate slug based on content title",
+ "category": "Front matter"
+ },
{
"command": "frontMatter.markup.heading",
"title": "Heading",
@@ -936,12 +1087,63 @@
}
},
{
- "command": "frontMatter.markup.unorderedlist",
- "title": "Unordered list",
+ "command": "frontMatter.init",
+ "title": "Initialize project",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.insertCategories",
+ "title": "Insert categories",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.insertImage",
+ "title": "Insert image into your content",
"category": "Front matter",
"icon": {
- "light": "assets/icons/unordered-list-light.svg",
- "dark": "assets/icons/unordered-list-dark.svg"
+ "dark": "/assets/icons/media-dark.svg",
+ "light": "/assets/icons/media-light.svg"
+ }
+ },
+ {
+ "command": "frontMatter.insertTags",
+ "title": "Insert tags",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.markup.italic",
+ "title": "Italic",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/italic-light.svg",
+ "dark": "assets/icons/italic-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.dashboard",
+ "title": "Open dashboard",
+ "category": "Front matter",
+ "icon": {
+ "dark": "/assets/icons/frontmatter-small-dark.svg",
+ "light": "/assets/icons/frontmatter-small-light.svg"
+ }
+ },
+ {
+ "command": "frontMatter.dashboard.data",
+ "title": "Open data dashboard",
+ "category": "Front matter",
+ "icon": {
+ "dark": "/assets/icons/frontmatter-small-dark.svg",
+ "light": "/assets/icons/frontmatter-small-light.svg"
+ }
+ },
+ {
+ "command": "frontMatter.dashboard.media",
+ "title": "Open media dashboard",
+ "category": "Front matter",
+ "icon": {
+ "dark": "/assets/icons/frontmatter-small-dark.svg",
+ "light": "/assets/icons/frontmatter-small-light.svg"
}
},
{
@@ -953,11 +1155,6 @@
"dark": "assets/icons/ordered-list-dark.svg"
}
},
- {
- "command": "frontMatter.markup.tasklist",
- "title": "Task list",
- "category": "Front matter"
- },
{
"command": "frontMatter.markup.options",
"title": "Other markup options",
@@ -968,9 +1165,47 @@
}
},
{
- "command": "frontMatter.diagnostics",
- "title": "Diagnostic logging",
+ "command": "frontMatter.preview",
+ "title": "Preview content",
"category": "Front matter"
+ },
+ {
+ "command": "frontMatter.promoteSettings",
+ "title": "Promote settings from local to team level",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.remap",
+ "title": "Remap or remove tag/category in all articles",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.setLastModifiedDate",
+ "title": "Set lastmod date",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.markup.strikethrough",
+ "title": "Strikethrough",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/strikethrough-light.svg",
+ "dark": "assets/icons/strikethrough-dark.svg"
+ }
+ },
+ {
+ "command": "frontMatter.markup.tasklist",
+ "title": "Task list",
+ "category": "Front matter"
+ },
+ {
+ "command": "frontMatter.markup.unorderedlist",
+ "title": "Unordered list",
+ "category": "Front matter",
+ "icon": {
+ "light": "assets/icons/unordered-list-light.svg",
+ "dark": "assets/icons/unordered-list-dark.svg"
+ }
}
],
"menus": {
@@ -1164,10 +1399,13 @@
"build:ext": "npm run clean && npm-run-all --parallel dev:build:*",
"watch:ext": "webpack --mode development --watch --config ./webpack/extension.config.js",
"watch:dashboard": "webpack serve --mode development --config ./webpack/dashboard.config.js",
+ "watch:panel": "webpack serve --mode development --config ./webpack/panel.config.js",
"dev:build:ext": "webpack --mode development --config ./webpack/extension.config.js",
"dev:build:dashboard": "webpack --mode development --config ./webpack/dashboard.config.js",
+ "dev:build:panel": "webpack --mode development --config ./webpack/panel.config.js",
"prod:ext": "webpack --mode production --config ./webpack/extension.config.js",
"prod:dashboard": "webpack --mode production --config ./webpack/dashboard.config.js",
+ "prod:panel": "webpack --mode production --config ./webpack/panel.config.js",
"test-compile": "tsc -p ./",
"clean": "rimraf dist",
"start:site": "cd ./docs && npm run dev"
@@ -1178,6 +1416,7 @@
"@headlessui/react": "^1.4.1",
"@heroicons/react": "1.0.4",
"@iarna/toml": "2.2.3",
+ "@octokit/rest": "^18.12.0",
"@sentry/react": "^6.13.3",
"@sentry/tracing": "^6.13.3",
"@tailwindcss/forms": "^0.3.3",
@@ -1186,6 +1425,7 @@
"@types/lodash.uniqby": "4.7.6",
"@types/mocha": "^5.2.6",
"@types/node": "10.17.48",
+ "@types/node-fetch": "^2.5.12",
"@types/react": "17.0.0",
"@types/react-datepicker": "^4.1.7",
"@types/react-dom": "17.0.0",
@@ -1193,6 +1433,8 @@
"@vscode/codicons": "0.0.20",
"@vscode/webview-ui-toolkit": "^0.8.1",
"@webpack-cli/serve": "^1.6.0",
+ "ajv": "^8.8.2",
+ "array-move": "^4.0.0",
"autoprefixer": "^10.3.2",
"css-loader": "5.2.7",
"date-fns": "2.23.0",
@@ -1211,22 +1453,32 @@
"path-browserify": "^1.0.1",
"postcss": "^8.3.6",
"postcss-loader": "4.3.0",
+ "postcss-nested": "^5.0.6",
"react": "17.0.1",
"react-datepicker": "4.2.1",
"react-dom": "17.0.1",
"react-dropzone": "^11.3.4",
+ "react-sortable-hoc": "^2.0.0",
+ "react-toastify": "^8.1.0",
"recoil": "^0.4.1",
"rimraf": "^3.0.2",
"style-loader": "2.0.0",
"tailwindcss": "^2.2.7",
"ts-loader": "8.0.3",
"tslint": "6.1.3",
- "typescript": "4.0.2",
+ "typescript": "^4.5.4",
+ "uniforms": "^3.7.0",
+ "uniforms-antd": "^3.7.0",
+ "uniforms-bridge-json-schema": "^3.7.0",
+ "uniforms-unstyled": "^3.7.0",
"url-join-ts": "^1.0.5",
"wc-react": "github:estruyf/wc-react",
"webpack": "^5.65.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.1",
"webpack-dev-server": "^4.6.0"
+ },
+ "dependencies": {
+ "node-fetch": "^2.6.7"
}
-}
+}
\ No newline at end of file
diff --git a/postcss.config.js b/postcss.config.js
index f8e23b97..a44e167f 100644
--- a/postcss.config.js
+++ b/postcss.config.js
@@ -2,6 +2,7 @@ const tailwindcss = require('tailwindcss');
module.exports = {
plugins: [
+ require('postcss-nested'),
tailwindcss('./tailwind.config.js'),
require('autoprefixer'),
],
diff --git a/src/commands/Article.ts b/src/commands/Article.ts
index 5e4a228f..cfd5e11f 100644
--- a/src/commands/Article.ts
+++ b/src/commands/Article.ts
@@ -1,7 +1,7 @@
import { isValidFile } from './../helpers/isValidFile';
-import { SETTING_AUTO_UPDATE_DATE, SETTING_MODIFIED_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_TEMPLATES_PREFIX, CONFIG_KEY, SETTING_DATE_FORMAT, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX } from './../constants';
+import { SETTING_AUTO_UPDATE_DATE, SETTING_MODIFIED_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_TEMPLATES_PREFIX, CONFIG_KEY, SETTING_DATE_FORMAT, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTINGS_CONTENT_PLACEHOLDERS } from './../constants';
import * as vscode from 'vscode';
-import { TaxonomyType } from "../models";
+import { Field, TaxonomyType } from "../models";
import { format } from "date-fns";
import { ArticleHelper, Settings, SlugHelper } from '../helpers';
import matter = require('gray-matter');
@@ -180,11 +180,34 @@ export class Article {
return;
}
- const articleTitle: string = article.data["title"];
- let slug = SlugHelper.createSlug(articleTitle);
+ const contentType = ArticleHelper.getContentType(article.data);
+ const titleField = "title";
+ const articleTitle: string = article.data[titleField];
+
+ const slug = SlugHelper.createSlug(articleTitle);
if (slug) {
- slug = `${prefix}${slug}${suffix}`;
- article.data["slug"] = slug;
+ let slugFieldValue = `${prefix}${slug}${suffix}`;
+ article.data["slug"] = slugFieldValue;
+
+ if (contentType) {
+ // Update the fields containing the slug placeholder
+ let fieldsToUpdate: Field[] = contentType.fields.filter(f => f.default === "{{slug}}");
+ for (const field of fieldsToUpdate) {
+ article.data[field.name] = slug;
+ }
+
+ // Update the fields containing a custom placeholder that depends on slug
+ const placeholders = Settings.get<{id: string, value: string}[]>(SETTINGS_CONTENT_PLACEHOLDERS);
+ const customPlaceholders = placeholders?.filter(p => p.value.includes("{{slug}}"));
+ for (const customPlaceholder of (customPlaceholders || [])) {
+ const customPlaceholderFields = contentType.fields.filter(f => f.default === `{{${customPlaceholder.id}}}`);
+ for (const pField of customPlaceholderFields) {
+ article.data[pField.name] = customPlaceholder.value;
+ article.data[pField.name] = ArticleHelper.processKnownPlaceholders(article.data[pField.name], articleTitle);
+ }
+ }
+ }
+
ArticleHelper.update(editor, article);
// Check if the file name should be updated by the slug
diff --git a/src/commands/Backers.ts b/src/commands/Backers.ts
new file mode 100644
index 00000000..215a03eb
--- /dev/null
+++ b/src/commands/Backers.ts
@@ -0,0 +1,74 @@
+import { commands, ExtensionContext } from 'vscode';
+import { CONTEXT } from '../constants';
+import { Extension } from '../helpers';
+import { Credentials } from "../services/Credentials";
+import fetch from "node-fetch";
+import { ExplorerView } from '../explorerView/ExplorerView';
+import { Dashboard } from './Dashboard';
+
+export class Backers {
+ private static creds: Credentials | null = null;
+
+ public static async init(context: ExtensionContext) {
+ Backers.creds = new Credentials();
+ await Backers.creds.initialize(context, Backers.tryUsernameCheck);
+
+ Backers.tryUsernameCheck();
+
+ context.subscriptions.push(
+ commands.registerCommand('frontMatter.authenticate', async () => {
+ Backers.tryUsernameCheck();
+ })
+ );
+ }
+
+ public static async tryUsernameCheck() {
+ try {
+ const username = await Backers.getUsername();
+ Backers.validate(username || "");
+ } catch (e) {
+ Backers.validate("");
+ }
+ }
+
+ public static async getUsername() {
+ const octokit = await Backers.creds?.getOctokit();
+ const user = await octokit?.users.getAuthenticated();
+
+ if (user?.data?.login) {
+ return user?.data?.login;
+ }
+
+ return;
+ }
+
+ public static async validate(username: string) {
+ const ext = Extension.getInstance();
+
+ if (!username) {
+ ext.setState(CONTEXT.backer, undefined, 'global');
+ }
+
+ const isBeta = ext.isBetaVersion();
+
+ const response = await fetch(`https://${isBeta ? `beta.` : ``}frontmatter.codes/api/backers?backer=${username}`);
+
+ if (response.ok) {
+ const prevData = await ext.getState(CONTEXT.backer, 'global');
+ await ext.setState(CONTEXT.backer, true, 'global');
+
+ if (!prevData) {
+ const explorerView = ExplorerView.getInstance();
+ if (explorerView.visible) {
+ explorerView.getSettings();
+ }
+
+ if (Dashboard.isOpen) {
+ Dashboard.reload();
+ }
+ }
+ } else {
+ ext.setState(CONTEXT.backer, false, 'global');
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/commands/Dashboard.ts b/src/commands/Dashboard.ts
index a54e89f4..23e4900c 100644
--- a/src/commands/Dashboard.ts
+++ b/src/commands/Dashboard.ts
@@ -11,6 +11,7 @@ import { DashboardData } from '../models/DashboardData';
import { ExplorerView } from '../explorerView/ExplorerView';
import { MediaLibrary } from '../helpers/MediaLibrary';
import { DashboardListener, MediaListener, SettingsListener } from '../listeners';
+import { DataListener } from '../listeners/DataListener';
export class Dashboard {
private static webview: WebviewPanel | null = null;
@@ -144,6 +145,7 @@ export class Dashboard {
MediaListener.process(msg);
PagesListener.process(msg);
SettingsListener.process(msg);
+ DataListener.process(msg);
});
}
@@ -175,14 +177,15 @@ export class Dashboard {
*/
private static getWebviewContent(webView: Webview, extensionPath: Uri): string {
const dashboardFile = "dashboardWebView.js";
- const localServerUrl = "http://localhost:9000";
+ const localPort = `9000`;
+ const localServerUrl = `localhost:${localPort}`;
let scriptUri = "";
const isProd = Extension.getInstance().isProductionMode;
if (isProd) {
scriptUri = webView.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile)).toString();
} else {
- scriptUri = `${localServerUrl}/${dashboardFile}`;
+ scriptUri = `http://${localServerUrl}/${dashboardFile}`;
}
const nonce = WebviewHelper.getNonce();
@@ -194,10 +197,10 @@ export class Dashboard {
const csp = [
`default-src 'none';`,
`img-src ${`vscode-file://vscode-app`} ${webView.cspSource} https://api.visitorbadge.io 'self' 'unsafe-inline'`,
- `script-src ${isProd ? `'nonce-${nonce}'` : "http://localhost:9000 http://0.0.0.0:9000"}`,
+ `script-src ${isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`} 'unsafe-eval'`,
`style-src ${webView.cspSource} 'self' 'unsafe-inline'`,
`font-src ${webView.cspSource}`,
- `connect-src https://o1022172.ingest.sentry.io ${isProd ? `` : "ws://localhost:9000 ws://0.0.0.0:9000 http://localhost:9000 http://0.0.0.0:9000"}`
+ `connect-src https://o1022172.ingest.sentry.io ${isProd ? `` : `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`}`
];
return `
diff --git a/src/commands/Folders.ts b/src/commands/Folders.ts
index f81e9e57..99116690 100644
--- a/src/commands/Folders.ts
+++ b/src/commands/Folders.ts
@@ -1,5 +1,5 @@
import { Questions } from './../helpers/Questions';
-import { SETTINGS_CONTENT_PAGE_FOLDERS, SETTINGS_CONTENT_STATIC_FOLDER } from './../constants';
+import { SETTINGS_CONTENT_PAGE_FOLDERS, SETTINGS_CONTENT_STATIC_FOLDER, SETTINGS_CONTENT_SUPPORTED_FILETYPES } from './../constants';
import { commands, Uri, workspace, window } from "vscode";
import { basename, join } from "path";
import { ContentFolder, FileInfo, FolderInfo } from "../models";
@@ -13,6 +13,7 @@ import { Dashboard } from './Dashboard';
import { parseWinPath } from '../helpers/parseWinPath';
import { MediaHelpers } from '../helpers/MediaHelpers';
import { MediaListener, PagesListener } from '../listeners';
+import { DEFAULT_FILE_TYPES } from '../constants/DefaultFileTypes';
export const WORKSPACE_PLACEHOLDER = `[[workspace]]`;
@@ -202,6 +203,7 @@ export class Folders {
* Get the registered folders information
*/
public static async getInfo(limit?: number): Promise {
+ const supportedFiles = Settings.get(SETTINGS_CONTENT_SUPPORTED_FILETYPES);
const folders = Folders.get();
if (folders && folders.length > 0) {
let folderInfo: FolderInfo[] = [];
@@ -214,10 +216,15 @@ export class Folders {
if (projectStart) {
projectStart = projectStart.replace(/\\/g, '/');
projectStart = projectStart.startsWith('/') ? projectStart.substr(1) : projectStart;
- const mdFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.md'));
- const markdownFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.markdown'));
- const mdxFiles = await workspace.findFiles(join(projectStart, folder.excludeSubdir ? '/' : '**/', '*.mdx'));
- let files = [...mdFiles, ...markdownFiles, ...mdxFiles];
+
+ let files: Uri[] = [];
+
+ for (const fileType of (supportedFiles || DEFAULT_FILE_TYPES)) {
+ const filePath = join(projectStart, folder.excludeSubdir ? '/' : '**', `*${fileType.startsWith('.') ? '' : '.'}${fileType}`);
+ const foundFiles = await workspace.findFiles(filePath, '**/node_modules/**');
+ files = [...files, ...foundFiles];
+ }
+
if (files) {
let fileStats: FileInfo[] = [];
@@ -274,6 +281,19 @@ export class Folders {
path: Folders.absWsFolder(folder, wsFolder)
}));
}
+
+ /**
+ * Retrieve the absolute file path
+ * @param filePath
+ * @returns
+ */
+ public static getAbsFilePath(filePath: string): string {
+ const wsFolder = Folders.getWorkspaceFolder();
+ const isWindows = process.platform === 'win32';
+ let absPath = filePath.replace(WORKSPACE_PLACEHOLDER, parseWinPath(wsFolder?.fsPath || ""));
+ absPath = isWindows ? absPath.split('/').join('\\') : absPath;
+ return absPath;
+ }
/**
* Update the folder settings
@@ -318,4 +338,8 @@ export class Folders {
absPath = isWindows ? absPath.split('\\').join('/') : absPath;
return absPath;
}
-}
\ No newline at end of file
+}
+
+function SETTINGS_CONTENT_SUPPORTED_FILES(SETTINGS_CONTENT_SUPPORTED_FILES: any) {
+ throw new Error('Function not implemented.');
+}
diff --git a/src/commands/Project.ts b/src/commands/Project.ts
index f11d7f90..e46cfc9c 100644
--- a/src/commands/Project.ts
+++ b/src/commands/Project.ts
@@ -10,8 +10,8 @@ import { SETTINGS_CONTENT_DEFAULT_FILETYPE } from "../constants";
export class Project {
private static content = `---
-title: "{{name}}"
-slug: "/{{kebabCase name}}/"
+title:
+slug:
description:
author:
date: 2019-08-22T15:20:28.000Z
diff --git a/src/commands/Template.ts b/src/commands/Template.ts
index d3e4ddc8..c63045c8 100644
--- a/src/commands/Template.ts
+++ b/src/commands/Template.ts
@@ -159,13 +159,7 @@ export class Template {
}
if (frontMatter.data) {
- const fmData = frontMatter.data;
- if (typeof fmData.title !== "undefined") {
- fmData.title = titleValue;
- }
- if (typeof fmData.slug !== "undefined") {
- fmData.slug = ArticleHelper.sanitize(titleValue);
- }
+ frontMatter.data = ArticleHelper.updatePlaceholders(frontMatter.data, titleValue);
frontMatter = Article.updateDate(frontMatter);
diff --git a/src/constants/DefaultFileTypes.ts b/src/constants/DefaultFileTypes.ts
new file mode 100644
index 00000000..a71cdc3d
--- /dev/null
+++ b/src/constants/DefaultFileTypes.ts
@@ -0,0 +1,3 @@
+
+
+export const DEFAULT_FILE_TYPES = [".md", ".markdown", ".mdx"];
\ No newline at end of file
diff --git a/src/constants/Extension.ts b/src/constants/Extension.ts
index 0afeff0d..561a0541 100644
--- a/src/constants/Extension.ts
+++ b/src/constants/Extension.ts
@@ -29,6 +29,7 @@ export const COMMAND_NAME = {
preview: getCommandName("preview"),
dashboard: getCommandName("dashboard"),
dashboardMedia: getCommandName("dashboard.media"),
+ dashboardData: getCommandName("dashboard.data"),
dashboardClose: getCommandName("dashboard.close"),
promote: getCommandName("promoteSettings"),
insertImage: getCommandName("insertImage"),
diff --git a/src/constants/FrameworkDetectors.ts b/src/constants/FrameworkDetectors.ts
index 5433233d..b15a7925 100644
--- a/src/constants/FrameworkDetectors.ts
+++ b/src/constants/FrameworkDetectors.ts
@@ -2,20 +2,32 @@ export const FrameworkDetectors = [
{
"framework": {"name": "gatsby", "dist": "public", "static": "static", "build": "gatsby build"},
"requiredFiles": ["gatsby-config.js"],
- "requiredDependencies": ["gatsby"]
+ "requiredDependencies": ["gatsby"],
+ "commands": {
+ "start": "npx gatsby develop"
+ }
},
{
"framework": {"name": "hugo", "dist": "public", "static": "static", "build": "hugo"},
- "requiredFiles": ["config.toml", "config.yaml", "config.yml"]
+ "requiredFiles": ["config.toml", "config.yaml", "config.yml"],
+ "commands": {
+ "start": "hugo server -D"
+ }
},
{
"framework": {"name": "next", "dist": ".next", "static": "public", "build": "next build"},
"requiredFiles": ["next.config.js"],
- "requiredDependencies": ["next"]
+ "requiredDependencies": ["next"],
+ "commands": {
+ "start": "npx next dev"
+ }
},
{
"framework": {"name": "nuxt", "dist": "dist", "static": "static", "build": "nuxt"},
"requiredFiles": ["nuxt.config.js"],
- "requiredDependencies": ["nuxt"]
+ "requiredDependencies": ["nuxt"],
+ "commands": {
+ "start": "npx nuxt"
+ }
}
];
\ No newline at end of file
diff --git a/src/constants/context.ts b/src/constants/context.ts
index 376640ad..8f029de2 100644
--- a/src/constants/context.ts
+++ b/src/constants/context.ts
@@ -5,4 +5,5 @@ export const CONTEXT = {
isEnabled: "frontMatter:enabled",
isDashboardOpen: "frontMatter:dashboard:open",
wysiwyg: "frontMatter:markdown:wysiwyg",
+ backer: "frontMatter:backers:supporter",
};
\ No newline at end of file
diff --git a/src/constants/settings.ts b/src/constants/settings.ts
index 3826ec3d..31e2b535 100644
--- a/src/constants/settings.ts
+++ b/src/constants/settings.ts
@@ -46,16 +46,23 @@ export const SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT = "content.fmHighlight";
export const SETTINGS_CONTENT_DRAFT_FIELD = "content.draftField";
export const SETTINGS_CONTENT_SORTING = "content.sorting";
export const SETTINGS_CONTENT_WYSIWYG = "content.wysiwyg";
+export const SETTINGS_CONTENT_PLACEHOLDERS = "content.placeholders";
export const SETTINGS_CONTENT_SORTING_DEFAULT = "content.defaultSorting";
export const SETTINGS_MEDIA_SORTING_DEFAULT = "content.defaultSorting";
export const SETTINGS_CONTENT_DEFAULT_FILETYPE = "content.defaultFileType";
+export const SETTINGS_CONTENT_SUPPORTED_FILETYPES = "content.supportedFileTypes";
export const SETTINGS_DASHBOARD_OPENONSTART = "dashboard.openOnStart";
export const SETTINGS_DASHBOARD_MEDIA_SNIPPET = "dashboard.mediaSnippet";
+export const SETTINGS_DATA_FILES = "data.files";
+export const SETTINGS_DATA_FOLDERS = "data.folders";
+export const SETTINGS_DATA_TYPES = "data.types";
+
export const SETTINGS_FRAMEWORK_ID = "framework.id";
+export const SETTINGS_FRAMEWORK_START = "framework.startCommand";
export const SETTING_SITE_BASEURL = "site.baseURL";
diff --git a/src/dashboardWebView/DashboardCommand.ts b/src/dashboardWebView/DashboardCommand.ts
index a44b26a0..eea46870 100644
--- a/src/dashboardWebView/DashboardCommand.ts
+++ b/src/dashboardWebView/DashboardCommand.ts
@@ -4,5 +4,6 @@ export enum DashboardCommand {
settings = "settings",
media = "media",
viewData = "viewData",
- mediaUpdate = "mediaUpdate"
+ mediaUpdate = "mediaUpdate",
+ dataFileEntries = "dataFileEntries"
}
\ No newline at end of file
diff --git a/src/dashboardWebView/DashboardMessage.ts b/src/dashboardWebView/DashboardMessage.ts
index 23dc81de..f7e4cab3 100644
--- a/src/dashboardWebView/DashboardMessage.ts
+++ b/src/dashboardWebView/DashboardMessage.ts
@@ -15,10 +15,13 @@ export enum DashboardMessage {
refreshMedia = 'refreshMedia',
uploadMedia = 'uploadMedia',
deleteMedia = 'deleteMedia',
+ revealMedia = 'revealMedia',
insertPreviewImage = 'insertPreviewImage',
updateMediaMetadata = 'updateMediaMetadata',
createMediaFolder = 'createMediaFolder',
setFramework = 'setFramework',
setState = 'setState',
runCustomScript = 'runCustomScript',
+ getDataEntries = 'getDataEntries',
+ putDataEntries = 'putDataEntries',
}
\ No newline at end of file
diff --git a/src/dashboardWebView/components/Button.tsx b/src/dashboardWebView/components/Button.tsx
index 8c7602f6..5ee9e5fe 100644
--- a/src/dashboardWebView/components/Button.tsx
+++ b/src/dashboardWebView/components/Button.tsx
@@ -1,15 +1,17 @@
import * as React from 'react';
export interface IButtonProps {
+ secondary?: boolean;
disabled?: boolean;
+ className?: string;
onClick: () => void;
}
-export const Button: React.FunctionComponent = ({onClick, disabled, children}: React.PropsWithChildren) => {
+export const Button: React.FunctionComponent = ({onClick, className, disabled, secondary, children}: React.PropsWithChildren) => {
return (
diff --git a/src/dashboardWebView/components/ChoiceButton.tsx b/src/dashboardWebView/components/ChoiceButton.tsx
index 623052b7..84929f4d 100644
--- a/src/dashboardWebView/components/ChoiceButton.tsx
+++ b/src/dashboardWebView/components/ChoiceButton.tsx
@@ -6,6 +6,7 @@ import { MenuItem, MenuItems } from './Menu';
export interface IChoiceButtonProps {
title: string;
choices: {
+ icon?: JSX.Element;
title: string;
disabled?: boolean;
onClick: () => void;
@@ -36,10 +37,19 @@ export const ChoiceButton: React.FunctionComponent = ({onCli
- {choices.map((choice) => (
+ {choices.map((choice, idx) => (
+ {choice.icon}
+ {choice.title}
+
+ ) : (
+ choice.title
+ )
+ )}
value={null}
onClick={choice.onClick}
disabled={choice.disabled} />
diff --git a/src/dashboardWebView/components/Contents/Contents.tsx b/src/dashboardWebView/components/Contents/Contents.tsx
index 16c5b56a..f3f90357 100644
--- a/src/dashboardWebView/components/Contents/Contents.tsx
+++ b/src/dashboardWebView/components/Contents/Contents.tsx
@@ -30,7 +30,7 @@ export const Contents: React.FunctionComponent = ({pages, loadin
{ loading ? : }
-
+
);
};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/Dashboard.tsx b/src/dashboardWebView/components/Dashboard.tsx
index 3ad406b0..5cfbd97c 100644
--- a/src/dashboardWebView/components/Dashboard.tsx
+++ b/src/dashboardWebView/components/Dashboard.tsx
@@ -8,6 +8,7 @@ import { DashboardViewSelector } from '../state';
import { Contents } from './Contents/Contents';
import { Media } from './Media/Media';
import { NavigationType } from '../models';
+import { DataView } from './DataView';
export interface IDashboardProps {
showWelcome: boolean;
@@ -30,15 +31,25 @@ export const Dashboard: React.FunctionComponent = ({showWelcome
return ;
}
+ if (view === NavigationType.Media) {
+ return (
+
+
+
+ );
+ }
+
+ if (view === NavigationType.Data) {
+ return (
+
+
+
+ );
+ }
+
return (
- {
- view === NavigationType.Media ? (
-
- ) : (
-
- )
- }
+
);
};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/DataView/DataForm.tsx b/src/dashboardWebView/components/DataView/DataForm.tsx
new file mode 100644
index 00000000..f5e74956
--- /dev/null
+++ b/src/dashboardWebView/components/DataView/DataForm.tsx
@@ -0,0 +1,69 @@
+import * as React from 'react';
+import Ajv from 'ajv';
+import { useEffect, useState } from 'react';
+import { JSONSchemaBridge } from 'uniforms-bridge-json-schema';
+import { AutoFields, AutoForm, ErrorsField } from 'uniforms-antd';
+import { ErrorBoundary } from '@sentry/react';
+import { DataFormControls } from './DataFormControls';
+
+export interface IDataFormProps {
+ schema: any;
+ model: any;
+ onSubmit: (model: any) => void;
+ onClear: () => void;
+}
+
+export const DataForm: React.FunctionComponent = ({ schema, model, onSubmit, onClear }: React.PropsWithChildren) => {
+ const [ bridge, setBridge ] = useState(null);
+
+ const ajv = new Ajv({ allErrors: true, useDefaults: true });
+
+ const jsonValidator = (schema: object) => {
+ const validator = ajv.compile(schema);
+
+ return (crntModel: object) => {
+ validator(crntModel);
+ return validator.errors?.length ? { details: validator.errors } : null;
+ };
+ }
+
+ useEffect(() => {
+ const schemaValidator = jsonValidator(schema);
+ const bridge = new JSONSchemaBridge(schema, schemaValidator);
+ setBridge(bridge);
+ }, [schema]);
+
+ if (!bridge) {
+ return null;
+ }
+
+ return (
+
+
+ {
+ model ? (
+
Modify the data
+ ) : (
+
Add new data
+ )
+ }
+
+
form?.reset()}>
+
+
+
+
+
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/DataView/DataFormControls.tsx b/src/dashboardWebView/components/DataView/DataFormControls.tsx
new file mode 100644
index 00000000..8efd735f
--- /dev/null
+++ b/src/dashboardWebView/components/DataView/DataFormControls.tsx
@@ -0,0 +1,25 @@
+import * as React from 'react';
+import { useForm } from 'uniforms';
+import { SubmitField } from 'uniforms-unstyled';
+import { Button } from '../Button';
+
+export interface IDataFormControlsProps {
+ model: any | null;
+ onClear: () => void;
+}
+
+export const DataFormControls: React.FunctionComponent = ({ model, onClear }: React.PropsWithChildren) => {
+ const { formRef } = useForm();
+
+ return (
+
+
+ {
+ if (onClear) {
+ onClear();
+ }
+ formRef.reset();
+ }}>Cancel
+
+ );
+};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/DataView/DataView.tsx b/src/dashboardWebView/components/DataView/DataView.tsx
new file mode 100644
index 00000000..52cbe75f
--- /dev/null
+++ b/src/dashboardWebView/components/DataView/DataView.tsx
@@ -0,0 +1,230 @@
+import * as React from 'react';
+import { Header } from '../Header';
+import { useRecoilValue } from 'recoil';
+import { SettingsSelector } from '../../state';
+import { DataForm } from './DataForm';
+import { useCallback, useEffect, useState } from 'react';
+import { DataFile } from '../../../models/DataFile';
+import { Messenger } from '@estruyf/vscode/dist/client';
+import { DashboardMessage } from '../../DashboardMessage';
+import { SponsorMsg } from '../SponsorMsg';
+import { EventData } from '@estruyf/vscode';
+import { DashboardCommand } from '../../DashboardCommand';
+import { Button } from '../Button';
+import { arrayMoveImmutable } from 'array-move';
+import { EmptyView } from './EmptyView';
+import { Container } from './SortableContainer';
+import { SortableItem } from './SortableItem';
+import { ChevronRightIcon } from '@heroicons/react/outline';
+import { ToastContainer, toast, Slide } from 'react-toastify';
+import 'react-toastify/dist/ReactToastify.css';
+import { DataType } from '../../../models/DataType';
+
+export interface IDataViewProps {}
+
+export const DataView: React.FunctionComponent = (props: React.PropsWithChildren) => {
+ const [ selectedData, setSelectedData ] = useState(null);
+ const [ selectedIndex, setSelectedIndex ] = useState(null);
+ const [ dataEntries, setDataEntries ] = useState(null);
+ const settings = useRecoilValue(SettingsSelector);
+
+ const setSchema = (dataFile: DataFile) => {
+ setSelectedData(dataFile);
+ setSelectedIndex(null);
+ setDataEntries(null);
+
+ Messenger.send(DashboardMessage.getDataEntries, { ...dataFile });
+ };
+
+ const messageListener = (message: MessageEvent>) => {
+ if (message.data.command === DashboardCommand.dataFileEntries) {
+ setDataEntries(message.data.data);
+ }
+ };
+
+ const deleteItem = useCallback((index: number) => {
+ const dataClone: any[] = Object.assign([], dataEntries);
+
+ if (!selectedData) {
+ return;
+ }
+
+ dataClone.splice(index, 1);
+ updateData(dataClone);
+ }, [selectedData, dataEntries]);
+
+
+ const onSubmit = useCallback((data: any) => {
+ const dataClone: any[] = Object.assign([], dataEntries);
+ if (selectedIndex !== null && selectedIndex !== undefined) {
+ dataClone[selectedIndex] = data;
+ } else {
+ dataClone.push(data);
+ }
+ updateData(dataClone);
+ }, [selectedData, dataEntries, selectedIndex]);
+
+
+ const onSortEnd = useCallback(({ oldIndex, newIndex }: any) => {
+ if (!dataEntries || dataEntries.length === 0) {
+ return null;
+ }
+
+ if (selectedIndex !== null && selectedIndex !== undefined) {
+ setSelectedIndex(newIndex);
+ }
+
+ const newEntries = arrayMoveImmutable(dataEntries, oldIndex, newIndex);
+ updateData(newEntries);
+ }, [selectedData, dataEntries, selectedIndex]);
+
+ const updateData = useCallback((data: any) => {
+ if (!selectedData) {
+ return;
+ }
+
+ Messenger.send(DashboardMessage.putDataEntries, {
+ file: selectedData.file,
+ fileType: selectedData.fileType,
+ entries: data
+ });
+
+ // Show toast message
+ toast.success("Updated your data entries", {
+ position: "top-right",
+ autoClose: 2000,
+ hideProgressBar: true,
+ closeOnClick: true,
+ pauseOnHover: false,
+ transition: Slide
+ });
+ }, [selectedData]);
+
+ useEffect(() => {
+ Messenger.listen(messageListener);
+
+ return () => {
+ Messenger.unlisten(messageListener);
+ }
+ }, []);
+
+ // Retrieve the data files, check if they have a schema or ID, if not, they shouldn't be shown
+ const dataFiles = (settings?.dataFiles || []).map((dataFile: DataFile) => {
+ if (!dataFile.schema && !dataFile.id) {
+ return null;
+ }
+
+ const clonedFile = Object.assign({}, dataFile);
+
+ if (clonedFile.type) {
+ const dataType = settings?.dataTypes?.find((dataType: DataType) => dataType.id === clonedFile.type);
+ if (!dataType) {
+ return null;
+ }
+ clonedFile.schema = Object.assign({}, dataType.schema);
+ }
+
+ return clonedFile;
+ }).filter(d => d !== null) as DataFile[];
+
+ return (
+
+
+
+
+
+
+
+
+ {
+ selectedData ? (
+ <>
+
+
Your {selectedData.title.toLowerCase()} data items
+
+
+ {
+ (dataEntries && dataEntries.length > 0) ? (
+ <>
+
+ {
+ (dataEntries || []).map((dataEntry, idx) => (
+ setSelectedIndex(index)}
+ onDeleteItem={deleteItem}
+ />
+ ))
+ }
+
+
setSelectedIndex(null)}>
+ Add a new entry
+
+ >
+ ) : (
+
+
No {selectedData.title.toLowerCase()} data entries found
+
+ )
+ }
+
+
+
+
Create or modify your {selectedData.title.toLowerCase()} data
+ {
+ selectedData ? (
+
setSelectedIndex(null)} />
+ ) : (
+ Select a data type to get started
+ )
+ }
+
+ >
+ ) : (
+
+ )
+ }
+
+
+
+
+
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/DataView/EmptyView.tsx b/src/dashboardWebView/components/DataView/EmptyView.tsx
new file mode 100644
index 00000000..975aa98a
--- /dev/null
+++ b/src/dashboardWebView/components/DataView/EmptyView.tsx
@@ -0,0 +1,13 @@
+import { ExclamationCircleIcon } from '@heroicons/react/outline';
+import * as React from 'react';
+
+export interface IEmptyViewProps {}
+
+export const EmptyView: React.FunctionComponent = (props: React.PropsWithChildren) => {
+ return (
+
+
+
Select your date type first
+
+ );
+};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/DataView/SortableContainer.tsx b/src/dashboardWebView/components/DataView/SortableContainer.tsx
new file mode 100644
index 00000000..1282a5d5
--- /dev/null
+++ b/src/dashboardWebView/components/DataView/SortableContainer.tsx
@@ -0,0 +1,6 @@
+import * as React from 'react';
+import { SortableContainer } from 'react-sortable-hoc';
+
+export interface ISortableContainerProps {}
+
+export const Container = SortableContainer(({ children }: React.PropsWithChildren) => ( ));
\ No newline at end of file
diff --git a/src/dashboardWebView/components/DataView/SortableItem.tsx b/src/dashboardWebView/components/DataView/SortableItem.tsx
new file mode 100644
index 00000000..b68054db
--- /dev/null
+++ b/src/dashboardWebView/components/DataView/SortableItem.tsx
@@ -0,0 +1,68 @@
+import { PencilIcon, SelectorIcon, TrashIcon, XIcon } from '@heroicons/react/outline';
+import * as React from 'react';
+import { SortableHandle, SortableElement } from 'react-sortable-hoc';
+import { Alert } from '../Modals/Alert';
+
+export interface ISortableItemProps {
+ value: string;
+ index: number;
+ crntIndex: number;
+ selectedIndex: number | null;
+ onSelectedIndexChange: (index: number) => void;
+ onDeleteItem: (index: number) => void;
+}
+
+const DragHandle = SortableHandle(() => );
+
+export const SortableItem = SortableElement(({ value, selectedIndex, crntIndex, onSelectedIndexChange, onDeleteItem }: ISortableItemProps) => {
+ const [ showAlert, setShowAlert ] = React.useState(false);
+
+ const deleteItemConfirm = () => {
+ setShowAlert(true);
+ };
+
+ return (
+ <>
+
+
+
+ {value}
+
+
+
+
onSelectedIndexChange(crntIndex)}>
+
+ Edit
+
+
deleteItemConfirm()}>
+
+ Delete
+
+
+
+
+ {
+ showAlert && (
+ setShowAlert(false)}
+ trigger={() => {
+ setShowAlert(false);
+ onDeleteItem(crntIndex);
+ }} />
+ )
+ }
+ >
+ );
+});
\ No newline at end of file
diff --git a/src/dashboardWebView/components/DataView/index.ts b/src/dashboardWebView/components/DataView/index.ts
new file mode 100644
index 00000000..59faaae1
--- /dev/null
+++ b/src/dashboardWebView/components/DataView/index.ts
@@ -0,0 +1 @@
+export * from './DataView';
diff --git a/src/dashboardWebView/components/Header/Header.tsx b/src/dashboardWebView/components/Header/Header.tsx
index 028f5f2d..b665cd94 100644
--- a/src/dashboardWebView/components/Header/Header.tsx
+++ b/src/dashboardWebView/components/Header/Header.tsx
@@ -13,11 +13,12 @@ import { useRecoilState, useResetRecoilState } from 'recoil';
import { CategoryAtom, DashboardViewAtom, SortingAtom, TagAtom } from '../../state';
import { Messenger } from '@estruyf/vscode/dist/client';
import { ClearFilters } from './ClearFilters';
-import { MarkdownIcon } from '../../../panelWebView/components/Icons/MarkdownIcon';
-import {PhotographIcon} from '@heroicons/react/outline';
import { MediaHeaderTop } from '../Media/MediaHeaderTop';
import { ChoiceButton } from '../ChoiceButton';
import { MediaHeaderBottom } from '../Media/MediaHeaderBottom';
+import { Tabs } from './Tabs';
+import { CustomScript } from '../../../models';
+import { LightningBoltIcon, PlusIcon } from '@heroicons/react/outline';
export interface IHeaderProps {
settings: Settings | null;
@@ -52,22 +53,25 @@ export const Header: React.FunctionComponent = ({totalPages, folde
resetSorting();
}
+ const runBulkScript = (script: CustomScript) => {
+ Messenger.send(DashboardMessage.runCustomScript, { script });
+ };
+
+ const customActions: any[] = (settings?.scripts || []).filter(s => s.bulk && (s.type === "content" || !s.type)).map((s, idx) => ({
+ title: (
+
+
+ {s.title}
+
+ ),
+ onClick: () => runBulkScript(s)
+ }));
+
return (
-
-
-
- updateView(NavigationType.Contents)}>
- Contents
-
-
-
- updateView(NavigationType.Media)}>
- Media
-
-
-
+
+
{
@@ -81,15 +85,28 @@ export const Header: React.FunctionComponent
= ({totalPages, folde
+
+ Create by content type
+
+ ),
+ onClick: createByContentType,
+ disabled: !settings?.initialized
+ }, {
+ title: (
+
+ ),
+ onClick: createByTemplate,
+ disabled: !settings?.initialized
+ },
+ ...customActions
+ ]}
onClick={createContent}
disabled={!settings?.initialized} />
diff --git a/src/dashboardWebView/components/Header/Sorting.tsx b/src/dashboardWebView/components/Header/Sorting.tsx
index 4e35c6f5..79963c62 100644
--- a/src/dashboardWebView/components/Header/Sorting.tsx
+++ b/src/dashboardWebView/components/Header/Sorting.tsx
@@ -10,6 +10,7 @@ import { NavigationType } from '../../models';
import { SortingOption } from '../../models/SortingOption';
import { SearchSelector, SettingsSelector, SortingAtom } from '../../state';
import { MenuButton, MenuItem, MenuItems } from '../Menu';
+import { Sorting as SortingHelpers } from '../../../helpers/Sorting';
export interface ISortingProps {
disableCustomSorting?: boolean;
@@ -23,6 +24,15 @@ export const sortOptions: SortingOption[] = [
{ name: "By filename (desc)", id: SortOption.FileNameDesc, order: SortOrder.desc, type: SortType.string },
];
+const mediaSortOptions: SortingOption[] = [
+ { name: "Size (asc)", id: SortOption.SizeAsc, order: SortOrder.asc, type: SortType.number },
+ { name: "Size (desc)", id: SortOption.SizeDesc, order: SortOrder.desc, type: SortType.number },
+ { name: "Caption (asc)", id: SortOption.CaptionAsc, order: SortOrder.asc, type: SortType.string },
+ { name: "Caption (desc)", id: SortOption.CaptionDesc, order: SortOrder.desc, type: SortType.string },
+ { name: "Alt (asc)", id: SortOption.AltAsc, order: SortOrder.asc, type: SortType.string },
+ { name: "Alt (desc)", id: SortOption.AltDesc, order: SortOrder.desc, type: SortType.string },
+];
+
export const Sorting: React.FunctionComponent = ({disableCustomSorting, view}: React.PropsWithChildren) => {
const [ crntSorting, setCrntSorting ] = useRecoilState(SortingAtom);
const searchValue = useRecoilValue(SearchSelector);
@@ -38,6 +48,13 @@ export const Sorting: React.FunctionComponent = ({disableCustomSo
};
let allOptions = [...sortOptions];
+
+ if (view === NavigationType.Media) {
+ allOptions = [...allOptions, ...mediaSortOptions];
+ }
+
+ allOptions = allOptions.sort(SortingHelpers.alphabetically("name"))
+
if (settings?.customSorting && !disableCustomSorting) {
allOptions = [...allOptions, ...settings.customSorting.map((s) => ({
title: s.title || s.name,
@@ -72,7 +89,7 @@ export const Sorting: React.FunctionComponent = ({disableCustomSo
-
+
{allOptions.map((option) => (
void;
+}
+
+export const Tab: React.FunctionComponent = ({navigationType, onNavigate, children}: React.PropsWithChildren) => {
+ const view = useRecoilValue(DashboardViewAtom);
+
+ return (
+ onNavigate(navigationType)}>
+ {children}
+
+ );
+};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/Header/Tabs.tsx b/src/dashboardWebView/components/Header/Tabs.tsx
new file mode 100644
index 00000000..35e664f4
--- /dev/null
+++ b/src/dashboardWebView/components/Header/Tabs.tsx
@@ -0,0 +1,45 @@
+import { DatabaseIcon, PhotographIcon } from '@heroicons/react/outline';
+import * as React from 'react';
+import { useRecoilValue } from 'recoil';
+import { MarkdownIcon } from '../../../panelWebView/components/Icons/MarkdownIcon';
+import { NavigationType } from '../../models';
+import { SettingsSelector } from '../../state';
+import { Tab } from './Tab';
+
+export interface ITabsProps {
+ onNavigate: (navigationType: NavigationType) => void;
+}
+
+export const Tabs: React.FunctionComponent = ({ onNavigate }: React.PropsWithChildren) => {
+ const settings = useRecoilValue(SettingsSelector);
+
+ return (
+
+
+
+ Contents
+
+
+
+
+ Media
+
+
+ {
+ (settings?.dataFiles && settings.dataFiles.length > 0) && (
+
+
+ Data
+
+
+ )
+ }
+
+ );
+};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/Media/FolderCreation.tsx b/src/dashboardWebView/components/Media/FolderCreation.tsx
index f35d6cb0..2258ceb1 100644
--- a/src/dashboardWebView/components/Media/FolderCreation.tsx
+++ b/src/dashboardWebView/components/Media/FolderCreation.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import {FolderAddIcon} from '@heroicons/react/outline';
+import {FolderAddIcon, LightningBoltIcon} from '@heroicons/react/outline';
import { useRecoilValue } from 'recoil';
import { DashboardMessage } from '../../DashboardMessage';
import { SelectedMediaFolderAtom, SettingsSelector } from '../../state';
@@ -31,6 +31,7 @@ export const FolderCreation: React.FunctionComponent = (pr
title={`Create new folder`}
choices={scripts.map(s => ({
title: s.title,
+ icon: ,
onClick: () => runCustomScript(s)
}))}
onClick={onFolderCreation}
diff --git a/src/dashboardWebView/components/Media/Item.tsx b/src/dashboardWebView/components/Media/Item.tsx
index f3706cef..35d5c6e8 100644
--- a/src/dashboardWebView/components/Media/Item.tsx
+++ b/src/dashboardWebView/components/Media/Item.tsx
@@ -1,6 +1,6 @@
import { Messenger } from '@estruyf/vscode/dist/client';
import { Menu } from '@headlessui/react';
-import { ClipboardIcon, CodeIcon, PencilIcon, PhotographIcon, PlusIcon, TrashIcon } from '@heroicons/react/outline';
+import { ClipboardIcon, CodeIcon, EyeIcon, PencilIcon, PhotographIcon, PlusIcon, TrashIcon } from '@heroicons/react/outline';
import { basename, dirname } from 'path';
import * as React from 'react';
import { useEffect } from 'react';
@@ -77,6 +77,7 @@ export const Item: React.FunctionComponent = ({media}: React.PropsWi
image: parseWinPath(relPath) || "",
file: viewData?.data?.filePath,
fieldName: viewData?.data?.fieldName,
+ parents: viewData?.data?.parents,
multiple: viewData?.data?.multiple,
value: viewData?.data?.value,
position: viewData?.data?.position || null,
@@ -107,6 +108,13 @@ export const Item: React.FunctionComponent = ({media}: React.PropsWi
setShowAlert(true);
};
+ const revealMedia = () => {
+ Messenger.send(DashboardMessage.revealMedia, {
+ file: media.fsPath,
+ folder: selectedFolder
+ });
+ };
+
const confirmDeletion = () => {
Messenger.send(DashboardMessage.deleteMedia, {
file: media.fsPath,
@@ -220,7 +228,7 @@ export const Item: React.FunctionComponent = ({media}: React.PropsWi
viewData?.data?.filePath ? (
<>
@@ -242,15 +250,15 @@ export const Item: React.FunctionComponent = ({media}: React.PropsWi
onClick={copyToClipboard}>
-
-
-
-
>
)
}
+
+
+
+
@@ -286,13 +294,17 @@ export const Item: React.FunctionComponent = ({media}: React.PropsWi
onClick={copyToClipboard} />
{ customScriptActions() }
-
-
>
)
}
+
+
+
+
diff --git a/src/dashboardWebView/components/Media/Media.tsx b/src/dashboardWebView/components/Media/Media.tsx
index 78062ca1..9b68ddf9 100644
--- a/src/dashboardWebView/components/Media/Media.tsx
+++ b/src/dashboardWebView/components/Media/Media.tsx
@@ -118,7 +118,7 @@ export const Media: React.FunctionComponent = (props: React.PropsWi
-
+
);
};
\ No newline at end of file
diff --git a/src/dashboardWebView/components/Menu/MenuItem.tsx b/src/dashboardWebView/components/Menu/MenuItem.tsx
index 99492359..f7643de5 100644
--- a/src/dashboardWebView/components/Menu/MenuItem.tsx
+++ b/src/dashboardWebView/components/Menu/MenuItem.tsx
@@ -2,7 +2,7 @@ import { Menu } from '@headlessui/react';
import * as React from 'react';
export interface IMenuItemProps {
- title: string;
+ title: JSX.Element | string;
value?: any;
isCurrent?: boolean;
disabled?: boolean;
diff --git a/src/dashboardWebView/components/SponsorMsg.tsx b/src/dashboardWebView/components/SponsorMsg.tsx
index ef0c3549..1a56d1a5 100644
--- a/src/dashboardWebView/components/SponsorMsg.tsx
+++ b/src/dashboardWebView/components/SponsorMsg.tsx
@@ -6,18 +6,28 @@ import { VersionInfo } from '../../models';
export interface ISponsorMsgProps {
beta: boolean | undefined;
version: VersionInfo | undefined;
+ isBacker: boolean | undefined;
}
-export const SponsorMsg: React.FunctionComponent = ({beta, version}: React.PropsWithChildren) => {
+export const SponsorMsg: React.FunctionComponent = ({beta, isBacker, version}: React.PropsWithChildren) => {
+
return (
-
-
- Support
-
- Front Matter{version ? ` (v${version.installedVersion}${!!beta ? ` BETA` : ''})` : ''}
-
- Review
-
+
+ {
+ isBacker ? (
+ Front Matter{version ? ` (v${version.installedVersion}${!!beta ? ` BETA` : ''})` : ''}
+ ) : (
+ <>
+
+ Support
+
+ Front Matter{version ? ` (v${version.installedVersion}${!!beta ? ` BETA` : ''})` : ''}
+
+ Review
+
+ >
+ )
+ }
);
};
\ No newline at end of file
diff --git a/src/dashboardWebView/constants/SortOption.ts b/src/dashboardWebView/constants/SortOption.ts
index 0d138217..71c676d4 100644
--- a/src/dashboardWebView/constants/SortOption.ts
+++ b/src/dashboardWebView/constants/SortOption.ts
@@ -2,5 +2,11 @@ export enum SortOption {
LastModifiedAsc = "LastModifiedAsc",
LastModifiedDesc = "LastModifiedDesc",
FileNameAsc = "FileNameAsc",
- FileNameDesc = "FileNameDesc"
+ FileNameDesc = "FileNameDesc",
+ SizeAsc = "SizeAsc",
+ SizeDesc = "SizeDesc",
+ CaptionAsc = "CaptionAsc",
+ CaptionDesc = "CaptionDesc",
+ AltAsc = "AltAsc",
+ AltDesc = "AltDesc",
}
\ No newline at end of file
diff --git a/src/dashboardWebView/hooks/useMessages.tsx b/src/dashboardWebView/hooks/useMessages.tsx
index fe696d37..fec94a32 100644
--- a/src/dashboardWebView/hooks/useMessages.tsx
+++ b/src/dashboardWebView/hooks/useMessages.tsx
@@ -26,6 +26,8 @@ export default function useMessages() {
setView(NavigationType.Media);
} else if (message.data.data?.type === NavigationType.Contents) {
setView(NavigationType.Contents);
+ } else if (message.data.data?.type === NavigationType.Data) {
+ setView(NavigationType.Data);
}
break;
case DashboardCommand.settings:
diff --git a/src/dashboardWebView/models/NavigationType.ts b/src/dashboardWebView/models/NavigationType.ts
index da02c4f4..eba82bf9 100644
--- a/src/dashboardWebView/models/NavigationType.ts
+++ b/src/dashboardWebView/models/NavigationType.ts
@@ -1,4 +1,5 @@
export enum NavigationType {
Contents = "contents",
- Media = "media"
+ Media = "media",
+ Data = "data",
}
\ No newline at end of file
diff --git a/src/dashboardWebView/models/Settings.ts b/src/dashboardWebView/models/Settings.ts
index 596b8f44..0dca39c7 100644
--- a/src/dashboardWebView/models/Settings.ts
+++ b/src/dashboardWebView/models/Settings.ts
@@ -1,8 +1,10 @@
+import { DataType } from './../../models/DataType';
import { VersionInfo } from '../../models/VersionInfo';
import { ContentFolder } from '../../models/ContentFolder';
import { ContentType, CustomScript, DraftField, Framework, SortingSetting } from '../../models';
import { SortingOption } from './SortingOption';
import { DashboardViewType } from '.';
+import { DataFile } from '../../models/DataFile';
export interface Settings {
beta: boolean;
@@ -24,6 +26,9 @@ export interface Settings {
customSorting: SortingSetting[] | undefined;
dashboardState: DashboardState;
scripts: CustomScript[];
+ dataFiles: DataFile[] | undefined;
+ dataTypes: DataType[] | undefined;
+ isBacker: boolean | undefined;
}
export interface DashboardState {
diff --git a/src/dashboardWebView/styles.css b/src/dashboardWebView/styles.css
index fe174556..e0f051aa 100644
--- a/src/dashboardWebView/styles.css
+++ b/src/dashboardWebView/styles.css
@@ -29,4 +29,270 @@
top: -1px;
left: 2px;
color: white;
+}
+
+.autoform {
+ @apply py-4;
+
+ h2 {
+ @apply text-sm mb-2;
+ }
+
+ form {
+ label {
+ @apply block;
+ @apply text-gray-500;
+ @apply my-2;
+ }
+
+ input {
+ @apply w-full text-vulcan-500 px-2 py-1;
+
+ &::placeholder {
+ @apply text-gray-500;
+ }
+ }
+
+ .ant-form-item-has-error .ant-form-item-control-input {
+ @apply relative;
+ }
+
+ .ant-form-item-has-error {
+ label {
+ &::after {
+ content: ' *';
+ @apply text-red-400;
+ }
+ }
+ }
+
+ .ant-form-item-has-error input {
+ @apply border border-red-400;
+ }
+
+ .ant-form-item-has-error .ant-form-item-children-icon {
+ @apply text-red-400 absolute right-1 top-1;
+
+ svg {
+ @apply w-4 h-4;
+ }
+ }
+
+ .errors {
+ > div {
+ @apply border border-red-400 !important;
+ }
+
+ ul {
+ @apply list-disc pl-6 pr-4 py-4 bg-opacity-50 text-vulcan-500;
+ }
+
+ li {
+ @apply capitalize text-gray-900;
+ }
+ }
+
+ input[type="submit"] {
+ @apply w-auto mt-4 inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium text-white bg-teal-600 cursor-pointer;
+
+ &:hover {
+ @apply bg-teal-700;
+ }
+
+ &:focus {
+ @apply outline-none;
+ }
+
+ &:disabled {
+ @apply bg-gray-500 opacity-50;
+ }
+ }
+ }
+
+ .fields {}
+
+ .ant-list.ant-list-bordered {
+ @apply border border-gray-300;
+ }
+
+ .ant-btn-dashed {
+ @apply border border-gray-300 border-dashed flex items-center justify-center py-1 mt-2;
+
+ &:hover {
+ @apply text-teal-900 border-teal-900;
+ }
+ }
+
+ .ant-input:hover, .ant-input-focused, .ant-input:focus {
+ @apply border-teal-600;
+ }
+
+ .ant-btn-ghost:focus, .ant-btn-ghost:hover {
+ @apply text-teal-600 border-teal-700;
+ }
+
+ .ant-switch-checked {
+ @apply bg-teal-500;
+ }
+
+ .ant-switch {
+ @apply bg-gray-400;
+
+ margin: 0;
+ padding: 0;
+ font-size: 14px;
+ font-variant: tabular-nums;
+ line-height: 1.5715;
+ list-style: none;
+ font-feature-settings: "tnum";
+ position: relative;
+ display: inline-block;
+ box-sizing: border-box;
+ min-width: 44px;
+ height: 22px;
+ line-height: 22px;
+ vertical-align: middle;
+ border: 0;
+ border-radius: 100px;
+ cursor: pointer;
+ transition: all .2s;
+ user-select: none;
+
+ &.ant-switch-checked {
+ @apply bg-teal-500;
+
+ .ant-switch-handle {
+ left: calc(100% - 20px);
+ }
+ }
+
+ .ant-switch-handle {
+ position: absolute;
+ top: 2px;
+ left: 2px;
+ width: 18px;
+ height: 18px;
+ transition: all .2s ease-in-out;
+
+ &::before {
+ position: absolute;
+ inset: 0;
+ background-color: #fff;
+ border-radius: 9px;
+ box-shadow: 0 2px 4px #00230b33;
+ transition: all .2s ease-in-out;
+ content: "";
+ }
+ }
+
+ .ant-switch-inner {
+ display: block;
+ margin: 0 7px 0 25px;
+ color: #fff;
+ font-size: 12px;
+ transition: margin .2s;
+
+ svg {
+ display: none;
+ }
+ }
+ }
+
+ .ant-input-number {
+ @apply border;
+
+ box-sizing: border-box;
+ font-variant: tabular-nums;
+ list-style: none;
+ font-feature-settings: "tnum";
+ position: relative;
+ width: 100%;
+ min-width: 0;
+ color: #000000d9;
+ font-size: 14px;
+ line-height: 1.5715;
+ background-color: #fff;
+ background-image: none;
+ transition: all .3s;
+ display: inline-block;
+ width: 90px;
+ margin: 0;
+ padding: 0;
+
+ &.ant-input-number-focused {
+ @apply border-teal-600;
+ }
+ }
+
+ .ant-input-number-handler {
+ position: relative;
+ display: block;
+ width: 100%;
+ height: 50%;
+ overflow: hidden;
+ color: #00000073;
+ font-weight: 700;
+ line-height: 0;
+ text-align: center;
+ border-left: 1px solid #d9d9d9;
+ transition: all .1s linear;
+ }
+
+ .ant-input-number-handler-wrap {
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 22px;
+ height: 100%;
+ background: #fff;
+ opacity: 0;
+ transition: opacity .24s linear .1s;
+ }
+
+ .ant-input-number-input {
+ @apply px-2 py-1;
+
+ width: 100%;
+ height: 30px;
+ text-align: left;
+ background-color: transparent;
+ border: 0;
+ outline: 0;
+ transition: all .3s linear;
+ appearance: textfield !important;
+ }
+
+ .ant-input-number:hover .ant-input-number-handler-wrap, .ant-input-number-focused .ant-input-number-handler-wrap {
+ opacity: 1;
+ }
+}
+
+.vscode-dark .autoform {
+ form {
+ label {
+ @apply text-whisper-900;
+ }
+
+ input[type="submit"] {
+ @apply text-vulcan-500
+ }
+
+ .errors {
+ li {
+ @apply text-white;
+ }
+ }
+ }
+
+ .ant-list.ant-list-bordered {
+ @apply border-vulcan-100;
+ }
+
+ .ant-btn-dashed {
+ @apply border-vulcan-50;
+
+ &:hover {
+ @apply text-teal-400 border-teal-900;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/explorerView/ExplorerView.ts b/src/explorerView/ExplorerView.ts
index 9d01b868..7cb73195 100644
--- a/src/explorerView/ExplorerView.ts
+++ b/src/explorerView/ExplorerView.ts
@@ -1,15 +1,15 @@
import { DashboardData } from '../models/DashboardData';
import { Template } from '../commands/Template';
-import { DefaultFields, SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, SETTING_AUTO_UPDATE_DATE, SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_PREVIEW_HOST, SETTING_DATE_FORMAT, SETTING_COMMA_SEPARATED_FIELDS, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_PANEL_FREEFORM, SETTING_SEO_DESCRIPTION_LENGTH, SETTING_SEO_TITLE_LENGTH, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_TAXONOMY_CATEGORIES, SETTING_TAXONOMY_TAGS, SETTINGS_CONTENT_DRAFT_FIELD, SETTING_SEO_SLUG_LENGTH, SETTING_SITE_BASEURL, SETTING_TAXONOMY_CUSTOM } from '../constants';
+import { DefaultFields, SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, SETTING_AUTO_UPDATE_DATE, SETTING_CUSTOM_SCRIPTS, SETTING_SEO_CONTENT_MIN_LENGTH, SETTING_SEO_DESCRIPTION_FIELD, SETTING_SLUG_UPDATE_FILE_NAME, SETTING_PREVIEW_HOST, SETTING_DATE_FORMAT, SETTING_COMMA_SEPARATED_FIELDS, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_PANEL_FREEFORM, SETTING_SEO_DESCRIPTION_LENGTH, SETTING_SEO_TITLE_LENGTH, SETTING_SLUG_PREFIX, SETTING_SLUG_SUFFIX, SETTING_TAXONOMY_CATEGORIES, SETTING_TAXONOMY_TAGS, SETTINGS_CONTENT_DRAFT_FIELD, SETTING_SEO_SLUG_LENGTH, SETTING_SITE_BASEURL, SETTING_TAXONOMY_CUSTOM, CONTEXT, SETTINGS_FRAMEWORK_ID, SETTINGS_FRAMEWORK_START } from '../constants';
import * as os from 'os';
import { PanelSettings, CustomScript as ICustomScript } from '../models/PanelSettings';
-import { CancellationToken, Disposable, Uri, Webview, WebviewView, WebviewViewProvider, WebviewViewResolveContext, window, workspace, commands, env as vscodeEnv } from "vscode";
+import { CancellationToken, Disposable, Uri, Webview, WebviewView, WebviewViewProvider, WebviewViewResolveContext, window, workspace, commands, env as vscodeEnv, ThemeIcon } from "vscode";
import { ArticleHelper, Settings } from "../helpers";
import { Command } from "../panelWebView/Command";
import { CommandToCode } from '../panelWebView/CommandToCode';
import { Article } from '../commands';
import { TagType } from '../panelWebView/TagType';
-import { CustomTaxonomyData, DraftField, ScriptType, TaxonomyType } from '../models';
+import { CustomTaxonomyData, DraftField, Field, ScriptType, TaxonomyType } from '../models';
import { exec } from 'child_process';
import { fromMarkdown } from 'mdast-util-from-markdown';
import { Content } from 'mdast';
@@ -101,13 +101,13 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
Article.toggleDraft();
break;
case CommandToCode.updateTags:
- this.updateTags(TagType.tags, msg.data || []);
+ this.updateTags(TagType.tags, msg.data?.values || [], msg.data?.parents || []);
break;
case CommandToCode.updateCategories:
- this.updateTags(TagType.categories, msg.data || []);
+ this.updateTags(TagType.categories, msg.data?.values || [], msg.data?.parents || []);
break;
case CommandToCode.updateKeywords:
- this.updateTags(TagType.keywords, msg.data || []);
+ this.updateTags(TagType.keywords, msg.data?.values || [], msg.data?.parents || []);
break;
case CommandToCode.updateCustomTaxonomy:
this.updateCustomTaxonomy(msg.data);
@@ -161,13 +161,13 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
await commands.executeCommand(COMMAND_NAME.createTemplate);
break;
case CommandToCode.updateModifiedUpdating:
- this.updateModifiedUpdating(msg.data || false);
+ this.updateSetting(SETTING_AUTO_UPDATE_DATE, msg.data || false);
break;
case CommandToCode.toggleWritingSettings:
this.toggleWritingSettings();
break;
case CommandToCode.updateFmHighlight:
- this.updateFmHighlight((msg.data !== null && msg.data !== undefined) ? msg.data : false);
+ this.updateSetting(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, (msg.data !== null && msg.data !== undefined) ? msg.data : false);
break;
case CommandToCode.toggleCenterMode:
await commands.executeCommand(`workbench.action.toggleCenteredLayout`);
@@ -179,7 +179,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
await commands.executeCommand(COMMAND_NAME.dashboard);
break;
case CommandToCode.updatePreviewUrl:
- this.updatePreviewUrl(msg.data || "");
+ this.updateSetting(SETTING_PREVIEW_HOST, msg.data || "");
break;
case CommandToCode.openInEditor:
openFileInEditor(msg.data);
@@ -194,6 +194,12 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
} as DashboardData);
this.getMediaSelection();
break;
+ case CommandToCode.frameworkCommand:
+ this.openTerminalWithCommand(msg.data.command);
+ break;
+ case CommandToCode.updateStartCommand:
+ await this.updateSetting(SETTINGS_FRAMEWORK_START, msg.data || "");
+ break;
}
});
@@ -249,32 +255,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
// Get the current content type
const contentType = ArticleHelper.getContentType(updatedMetadata);
if (contentType) {
- const imageFields = contentType.fields.filter((field) => field.type === "image");
-
- for (const field of imageFields) {
- if (updatedMetadata[field.name]) {
- const imageData = ImageHelper.allRelToAbs(field, updatedMetadata[field.name])
-
- if (imageData) {
- if (field.multiple && imageData instanceof Array) {
- const preview = imageData.map(preview => preview && preview.absPath ? ({
- ...preview,
- webviewUrl: this.panel?.webview.asWebviewUri(preview.absPath).toString()
- }) : null);
-
- updatedMetadata[field.name] = preview || [];
- } else if (!field.multiple && !Array.isArray(imageData) && imageData.absPath) {
- const preview = this.panel?.webview.asWebviewUri(imageData.absPath);
- updatedMetadata[field.name] = {
- ...imageData,
- webviewUrl: preview ? preview.toString() : null
- };
- }
- } else {
- updatedMetadata[field.name] = field.multiple ? [] : "";
- }
- }
- }
+ this.processImageFields(updatedMetadata, contentType.fields)
}
}
@@ -314,7 +295,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
/**
* Update the metadata of the article
*/
- public async updateMetadata({field, value }: { field: string, value: any, fieldData?: { multiple: boolean, value: string[] } }) {
+ public async updateMetadata({field, parents, value }: { field: string, value: any, parents?: string[], fieldData?: { multiple: boolean, value: string[] } }) {
if (!field) {
return;
}
@@ -333,12 +314,18 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
const dateFields = contentType.fields.filter((field) => field.type === "datetime");
const imageFields = contentType.fields.filter((field) => field.type === "image" && field.multiple);
+ // Support multi-level fields
+ let parentObj = article.data;
+ for (const parent of parents || []) {
+ parentObj = parentObj[parent];
+ }
+
for (const dateField of dateFields) {
if ((field === dateField.name) && value) {
- article.data[field] = Article.formatDate(new Date(value));
+ parentObj[field] = Article.formatDate(new Date(value));
} else if (!imageFields.find(f => f.name === field)) {
// Only override the field data if it is not an multiselect image field
- article.data[field] = value;
+ parentObj[field] = value;
}
}
@@ -346,15 +333,15 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
if (field === imageField.name) {
// If value is an array, it means it comes from the explorer view itself (deletion)
if (Array.isArray(value)) {
- article.data[field] = value || [];
+ parentObj[field] = value || [];
} else { // Otherwise it is coming from the media dashboard (addition)
- let fieldValue = article.data[field];
+ let fieldValue = parentObj[field];
if (fieldValue && !Array.isArray(fieldValue)) {
fieldValue = [fieldValue];
}
const crntData = Object.assign([], fieldValue);
const allRelPaths = [...(crntData || []), value];
- article.data[field] = [...new Set(allRelPaths)].filter(f => f);
+ parentObj[field] = [...new Set(allRelPaths)].filter(f => f);
}
}
}
@@ -363,6 +350,29 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
this.pushMetadata(article.data);
}
+ /**
+ * Open a terminal and run the passed command
+ * @param command
+ */
+ private openTerminalWithCommand(command: string) {
+ if (command) {
+ let terminal = window.activeTerminal;
+
+ if (!terminal || (terminal && terminal.state.isInteractedWith === true)) {
+ terminal = window.createTerminal({
+ name: `Starting local server`,
+ iconPath: new ThemeIcon('server-environment'),
+ message: `Starting local server`,
+ });
+ }
+
+ if (terminal) {
+ terminal.sendText(command);
+ terminal.show(false);
+ }
+ }
+ }
+
/**
* Run a custom script
* @param msg
@@ -423,7 +433,12 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
commaSeparatedFields: Settings.get(SETTING_COMMA_SEPARATED_FIELDS) || [],
contentTypes: Settings.get(SETTING_TAXONOMY_CONTENT_TYPES) || [],
dashboardViewData: Dashboard.viewData,
- draftField: Settings.get(SETTINGS_CONTENT_DRAFT_FIELD)
+ draftField: Settings.get(SETTINGS_CONTENT_DRAFT_FIELD),
+ isBacker: await Extension.getInstance().getState(CONTEXT.backer, 'global'),
+ framework: Settings.get(SETTINGS_FRAMEWORK_ID),
+ commands: {
+ start: Settings.get(SETTINGS_FRAMEWORK_START)
+ }
} as PanelSettings
});
}
@@ -438,6 +453,58 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
});
}
+ /**
+ * Process the image fields in the content type
+ * @param updatedMetadata
+ * @param fields
+ * @param parents
+ */
+ private processImageFields(updatedMetadata: any, fields: Field[], parents: string[] = []) {
+ const imageFields = fields.filter((field) => field.type === "image");
+
+ // Support multi-level fields
+ let parentObj = updatedMetadata;
+ for (const parent of parents || []) {
+ parentObj = parentObj[parent];
+ }
+
+ // Process image fields
+ if (parentObj) {
+ for (const field of imageFields) {
+ if (parentObj[field.name]) {
+ const imageData = ImageHelper.allRelToAbs(field, parentObj[field.name])
+
+ if (imageData) {
+ if (field.multiple && imageData instanceof Array) {
+ const preview = imageData.map(preview => preview && preview.absPath ? ({
+ ...preview,
+ webviewUrl: this.panel?.webview.asWebviewUri(preview.absPath).toString()
+ }) : null);
+
+ parentObj[field.name] = preview || [];
+ } else if (!field.multiple && !Array.isArray(imageData) && imageData.absPath) {
+ const preview = this.panel?.webview.asWebviewUri(imageData.absPath);
+ parentObj[field.name] = {
+ ...imageData,
+ webviewUrl: preview ? preview.toString() : null
+ };
+ }
+ } else {
+ parentObj[field.name] = field.multiple ? [] : "";
+ }
+ }
+ }
+
+ // Check if there are sub-fields to process
+ const subFields = fields.filter((field) => field.type === "fields");
+ if (subFields?.length > 0) {
+ for (const field of subFields) {
+ this.processImageFields(updatedMetadata, field.fields || [], [...parents, field.name]);
+ }
+ }
+ }
+ }
+
/**
* Retrieve the file its front matter
*/
@@ -458,7 +525,7 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
* @param tagType
* @param values
*/
- private updateTags(tagType: TagType, values: string[]) {
+ private updateTags(tagType: TagType, values: string[], parents: string[]) {
const editor = window.activeTextEditor;
if (!editor) {
return "";
@@ -466,7 +533,14 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
const article = ArticleHelper.getFrontMatter(editor);
if (article && article.data) {
- article.data[tagType.toLowerCase()] = values || [];
+
+ // Support multi-level fields
+ let parentObj = article.data;
+ for (const parent of parents || []) {
+ parentObj = parentObj[parent];
+ }
+
+ parentObj[tagType.toLowerCase()] = values || [];
ArticleHelper.update(editor, article);
this.pushMetadata(article!.data);
}
@@ -488,7 +562,14 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
const article = ArticleHelper.getFrontMatter(editor);
if (article && article.data) {
- article.data[data.name] = data.options || [];
+
+ // Support multi-level fields
+ let parentObj = article.data;
+ for (const parent of data.parents || []) {
+ parentObj = parentObj[parent];
+ }
+
+ parentObj[data.name] = data.options || [];
ArticleHelper.update(editor, article);
this.pushMetadata(article!.data);
}
@@ -656,26 +737,12 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
}
/**
- * Update the preview URL
+ * Updates a setting and refreshes the retrieved settings
+ * @param setting
+ * @param value
*/
- private async updatePreviewUrl(previewUrl: string) {
- await Settings.update(SETTING_PREVIEW_HOST, previewUrl);
- this.getSettings();
- }
-
- /**
- * Toggle the Front Matter highlighting
- */
- private async updateFmHighlight(autoUpdate: boolean) {
- await Settings.update(SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, autoUpdate);
- this.getSettings();
- }
-
- /**
- * Toggle the modified auto-update setting
- */
- private async updateModifiedUpdating(autoUpdate: boolean) {
- await Settings.update(SETTING_AUTO_UPDATE_DATE, autoUpdate);
+ private async updateSetting(setting: string, value: any) {
+ await Settings.update(setting, value);
this.getSettings();
}
@@ -692,35 +759,56 @@ export class ExplorerView implements WebviewViewProvider, Disposable {
* @param webView
*/
private getWebviewContent(webView: Webview): string {
+ const ext = Extension.getInstance();
+ const dashboardFile = "panelWebView.js";
+ const localPort = `9001`;
+ const localServerUrl = `localhost:${localPort}`;
+ const extensionPath = ext.extensionPath;
+
const styleVSCodeUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'assets/media', 'vscode.css'));
const styleResetUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'assets/media', 'reset.css'));
const stylesUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'assets/media', 'styles.css'));
- const scriptUri = webView.asWebviewUri(Uri.joinPath(this.extPath, 'dist', 'panelWebView.js'));
const nonce = WebviewHelper.getNonce();
- const ext = Extension.getInstance();
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
+ let scriptUri = "";
+ const isProd = Extension.getInstance().isProductionMode;
+ if (isProd) {
+ scriptUri = webView.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile)).toString();
+ } else {
+ scriptUri = `http://${localServerUrl}/${dashboardFile}`;
+ }
+
+ const csp = [
+ `default-src 'none';`,
+ `img-src ${`vscode-file://vscode-app`} ${webView.cspSource} https://api.visitorbadge.io 'self' 'unsafe-inline'`,
+ `script-src ${isProd ? `'nonce-${nonce}'` : `http://${localServerUrl} http://0.0.0.0:${localPort}`}`,
+ `style-src ${webView.cspSource} 'self' 'unsafe-inline'`,
+ `font-src ${webView.cspSource}`,
+ `connect-src https://o1022172.ingest.sentry.io ${isProd ? `` : `ws://${localServerUrl} ws://0.0.0.0:${localPort} http://${localServerUrl} http://0.0.0.0:${localPort}`}`
+ ];
+
return `
-
+
- Front Matter
+ Front Matter Panel
-
+
-
+
`;
diff --git a/src/extension.ts b/src/extension.ts
index 5b97b065..102070bb 100644
--- a/src/extension.ts
+++ b/src/extension.ts
@@ -19,6 +19,7 @@ import ContentProvider from './providers/ContentProvider';
import { Wysiwyg } from './commands/Wysiwyg';
import { Diagnostics } from './commands/Diagnostics';
import { PagesListener } from './listeners';
+import { Backers } from './commands/Backers';
let frontMatterStatusBar: vscode.StatusBarItem;
let statusDebouncer: { (fnc: any, time: number): void; };
@@ -31,6 +32,7 @@ export async function activate(context: vscode.ExtensionContext) {
const { subscriptions, extensionUri, extensionPath } = context;
const extension = Extension.getInstance(context);
+ Backers.init(context);
if (!extension.checkIfExtensionCanRun()) {
return undefined;
@@ -61,6 +63,10 @@ export async function activate(context: vscode.ExtensionContext) {
Dashboard.open({ type: "media" });
}));
+ subscriptions.push(vscode.commands.registerCommand(COMMAND_NAME.dashboardData, (data?: DashboardData) => {
+ Dashboard.open({ type: "data" });
+ }));
+
subscriptions.push(vscode.commands.registerCommand(COMMAND_NAME.dashboardClose, (data?: DashboardData) => {
Dashboard.close();
}));
diff --git a/src/helpers/ArticleHelper.ts b/src/helpers/ArticleHelper.ts
index 4a76af92..d70293ba 100644
--- a/src/helpers/ArticleHelper.ts
+++ b/src/helpers/ArticleHelper.ts
@@ -3,20 +3,21 @@ import { DEFAULT_CONTENT_TYPE, DEFAULT_CONTENT_TYPE_NAME } from './../constants/
import * as vscode from 'vscode';
import * as matter from "gray-matter";
import * as fs from "fs";
-import { DefaultFields, SETTINGS_CONTENT_DEFAULT_FILETYPE, SETTING_COMMA_SEPARATED_FIELDS, SETTING_DATE_FIELD, SETTING_DATE_FORMAT, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_TEMPLATES_PREFIX } from '../constants';
+import { DefaultFields, SETTINGS_CONTENT_DEFAULT_FILETYPE, SETTINGS_CONTENT_PLACEHOLDERS, SETTINGS_CONTENT_SUPPORTED_FILETYPES, SETTING_COMMA_SEPARATED_FIELDS, SETTING_DATE_FIELD, SETTING_DATE_FORMAT, SETTING_INDENT_ARRAY, SETTING_REMOVE_QUOTES, SETTING_TAXONOMY_CONTENT_TYPES, SETTING_TEMPLATES_PREFIX } from '../constants';
import { DumpOptions } from 'js-yaml';
import { TomlEngine, getFmLanguage, getFormatOpts } from './TomlEngine';
-import { Extension, Settings } from '.';
+import { Extension, Logger, Settings, SlugHelper } from '.';
import { format, parse } from 'date-fns';
import { Notifications } from './Notifications';
import { Article } from '../commands';
-import { basename, join } from 'path';
+import { join } from 'path';
import { EditorHelper } from '@estruyf/vscode';
import sanitize from '../helpers/Sanitize';
import { existsSync, mkdirSync } from 'fs';
import { ContentType } from '../models';
import { DateHelper } from './DateHelper';
-import { Diagnostic, DiagnosticSeverity, Position, window, Range } from 'vscode';
+import { DiagnosticSeverity, Position, window, Range } from 'vscode';
+import { DEFAULT_FILE_TYPES } from '../constants/DefaultFileTypes';
export class ArticleHelper {
private static notifiedFiles: string[] = [];
@@ -145,7 +146,8 @@ export class ArticleHelper {
*/
public static isMarkdownFile(document: vscode.TextDocument | undefined | null = null) {
const supportedLanguages = ["markdown", "mdx"];
- const supportedFileExtensions = [".md", ".mdx"];
+ const fileTypes = Settings.get(SETTINGS_CONTENT_SUPPORTED_FILETYPES);
+ const supportedFileExtensions = fileTypes ? fileTypes.map(f => f.startsWith(`.`) ? f : `.${f}`) : DEFAULT_FILE_TYPES;
const languageId = document?.languageId?.toLowerCase();
const isSupportedLanguage = languageId && supportedLanguages.includes(languageId);
document ??= vscode.window.activeTextEditor?.document;
@@ -274,6 +276,83 @@ export class ArticleHelper {
return newFilePath;
}
+ /**
+ * Update placeholder values in the front matter content
+ * @param data
+ * @param title
+ * @returns
+ */
+ public static updatePlaceholders(data: any, title: string) {
+ const fmData = Object.assign({}, data);
+
+ for (const fieldName of Object.keys(fmData)) {
+ const fieldValue = fmData[fieldName];
+
+ if (fieldName === "title" && (fieldValue === null || fieldValue === "")) {
+ fmData[fieldName] = title;
+ }
+
+ if (fieldName === "slug" && (fieldValue === null || fieldValue === "")) {
+ fmData[fieldName] = SlugHelper.createSlug(title);
+ }
+
+ fmData[fieldName] = this.processKnownPlaceholders(fmData[fieldName], title);
+ fmData[fieldName] = this.processCustomPlaceholders(fmData[fieldName], title);
+ }
+
+ return fmData;
+ }
+
+ /**
+ * Replace the known placeholders
+ * @param value
+ * @param title
+ * @returns
+ */
+ public static processKnownPlaceholders(value: string, title: string) {
+ if (value && typeof value === "string") {
+ if (value.includes("{{title}}")) {
+ const regex = new RegExp("{{title}}", "g");
+ value = value.replace(regex, title);
+ }
+
+ if (value.includes("{{slug}}")) {
+ const regex = new RegExp("{{slug}}", "g");
+ value = value.replace(regex, SlugHelper.createSlug(title) || "");
+ }
+
+ if (value.includes("{{now}}")) {
+ const regex = new RegExp("{{now}}", "g");
+ value = value.replace(regex, Article.formatDate(new Date()));
+ }
+ }
+
+ return value;
+ }
+
+ /**
+ * Replace the custom placeholders
+ * @param value
+ * @param title
+ * @returns
+ */
+ public static processCustomPlaceholders(value: string, title: string) {
+ if (value && typeof value === "string") {
+ const placeholders = Settings.get<{id: string, value: string}[]>(SETTINGS_CONTENT_PLACEHOLDERS);
+ if (placeholders && placeholders.length > 0) {
+ for (const placeholder of placeholders) {
+ if (value.includes(`{{${placeholder.id}}}`)) {
+ const regex = new RegExp(`{{${placeholder.id}}}`, "g");
+ const updatedValue = this.processKnownPlaceholders(placeholder.value, title);
+ value = value.replace(regex, updatedValue);
+ }
+ }
+ }
+ }
+
+ return value;
+ }
+
/**
* Parse a markdown file and its front matter
* @param fileContents
@@ -316,6 +395,8 @@ export class ArticleHelper {
await EditorHelper.showFile(fileName)
}
}];
+
+ Logger.error(error.message);
const editor = window.activeTextEditor;
if (editor?.document.uri) {
@@ -329,7 +410,6 @@ export class ArticleHelper {
fmRange = MarkdownFoldingProvider.getFrontMatterRange(editor.document);
}
-
if (fmRange) {
Extension.getInstance().diagnosticCollection.set(editor.document.uri, [{
severity: DiagnosticSeverity.Error,
diff --git a/src/helpers/ContentType.ts b/src/helpers/ContentType.ts
index a30d174c..c54e3e9e 100644
--- a/src/helpers/ContentType.ts
+++ b/src/helpers/ContentType.ts
@@ -1,7 +1,7 @@
import { PagesListener } from './../listeners/PagesListener';
import { ArticleHelper, Settings } from ".";
import { SETTINGS_CONTENT_DRAFT_FIELD, SETTING_TAXONOMY_CONTENT_TYPES } from "../constants";
-import { ContentType as IContentType, DraftField } from '../models';
+import { ContentType as IContentType, DraftField, Field } from '../models';
import { Uri, workspace, window, commands } from 'vscode';
import { Folders } from "../commands/Folders";
import { Questions } from "./Questions";
@@ -109,15 +109,7 @@ export class ContentType {
return;
}
- let data: any = {};
-
- for (const field of contentType.fields) {
- if (field.name === "title") {
- data[field.name] = titleValue;
- } else {
- data[field.name] = null;
- }
- }
+ let data: any = this.processFields(contentType, titleValue, {});
data = ArticleHelper.updateDates(Object.assign({}, data));
@@ -136,4 +128,34 @@ export class ContentType {
// Trigger a refresh for the dashboard
PagesListener.refresh();
}
+
+ /**
+ * Process all content type fields
+ * @param contentType
+ * @param data
+ */
+ private static processFields(obj: IContentType | Field, titleValue: string, data: any) {
+
+ if (obj.fields) {
+ for (const field of obj.fields) {
+ if (field.name === "title") {
+ if (field.default) {
+ data[field.name] = ArticleHelper.processKnownPlaceholders(field.default, titleValue);
+ data[field.name] = ArticleHelper.processCustomPlaceholders(data[field.name], titleValue);
+ } else {
+ data[field.name] = titleValue;
+ }
+ } else {
+ if (field.type === "fields") {
+ data[field.name] = this.processFields(field, titleValue, {});
+ } else {
+ data[field.name] = field.default ? ArticleHelper.processKnownPlaceholders(field.default, titleValue) : "";
+ data[field.name] = field.default ? ArticleHelper.processCustomPlaceholders(data[field.name], titleValue) : "";
+ }
+ }
+ }
+ }
+
+ return data;
+ }
}
\ No newline at end of file
diff --git a/src/helpers/DashboardSettings.ts b/src/helpers/DashboardSettings.ts
index 35bce516..de5faaaa 100644
--- a/src/helpers/DashboardSettings.ts
+++ b/src/helpers/DashboardSettings.ts
@@ -1,8 +1,13 @@
+import { basename, join } from "path";
+import { workspace } from "vscode";
import { Folders } from "../commands/Folders";
import { Template } from "../commands/Template";
-import { ExtensionState, SETTINGS_CONTENT_DRAFT_FIELD, SETTINGS_CONTENT_SORTING, SETTINGS_CONTENT_SORTING_DEFAULT, SETTINGS_CONTENT_STATIC_FOLDER, SETTINGS_DASHBOARD_MEDIA_SNIPPET, SETTINGS_DASHBOARD_OPENONSTART, SETTINGS_FRAMEWORK_ID, SETTINGS_MEDIA_SORTING_DEFAULT, SETTING_CUSTOM_SCRIPTS, SETTING_TAXONOMY_CONTENT_TYPES } from "../constants";
+import { CONTEXT, ExtensionState, SETTINGS_CONTENT_DRAFT_FIELD, SETTINGS_CONTENT_SORTING, SETTINGS_CONTENT_SORTING_DEFAULT, SETTINGS_CONTENT_STATIC_FOLDER, SETTINGS_DASHBOARD_MEDIA_SNIPPET, SETTINGS_DASHBOARD_OPENONSTART, SETTINGS_DATA_FILES, SETTINGS_DATA_FOLDERS, SETTINGS_DATA_TYPES, SETTINGS_FRAMEWORK_ID, SETTINGS_MEDIA_SORTING_DEFAULT, SETTING_CUSTOM_SCRIPTS, SETTING_TAXONOMY_CONTENT_TYPES } from "../constants";
import { DashboardViewType, SortingOption, Settings as ISettings } from "../dashboardWebView/models";
import { CustomScript, DraftField, ScriptType, SortingSetting, TaxonomyType } from "../models";
+import { DataFile } from "../models/DataFile";
+import { DataFolder } from "../models/DataFolder";
+import { DataType } from "../models/DataType";
import { Extension } from "./Extension";
import { FrameworkDetector } from "./FrameworkDetector";
import { Settings } from "./SettingsHelper";
@@ -33,7 +38,7 @@ export class DashboardSettings {
contentFolders: Folders.get(),
crntFramework: Settings.get(SETTINGS_FRAMEWORK_ID),
framework: (!isInitialized && wsFolder) ? FrameworkDetector.get(wsFolder.fsPath) : null,
- scripts: (Settings.get(SETTING_CUSTOM_SCRIPTS) || []).filter(s => s.type && s.type !== ScriptType.Content),
+ scripts: (Settings.get(SETTING_CUSTOM_SCRIPTS) || []),
dashboardState: {
contents: {
sorting: await ext.getState(ExtensionState.Dashboard.Contents.Sorting, "workspace"),
@@ -44,7 +49,58 @@ export class DashboardSettings {
defaultSorting: Settings.get(SETTINGS_MEDIA_SORTING_DEFAULT),
selectedFolder: await ext.getState(ExtensionState.SelectedFolder, "workspace")
}
- }
+ },
+ dataFiles: await this.getDataFiles(),
+ dataTypes: Settings.get(SETTINGS_DATA_TYPES),
+ isBacker: await ext.getState(CONTEXT.backer, 'global')
} as ISettings
}
+
+ /**
+ * Retrieve all the data files
+ * @returns
+ */
+ private static async getDataFiles(): Promise {
+ const wsPath = Folders.getWorkspaceFolder()?.fsPath;
+ const files = Settings.get(SETTINGS_DATA_FILES);
+ const folders = Settings.get(SETTINGS_DATA_FOLDERS);
+
+ let clonedFiles = Object.assign([], files);
+ if (folders) {
+ for (let folder of folders) {
+ if (!folder.path) {
+ continue;
+ }
+
+ const folderPath = Folders.getAbsFilePath(folder.path);
+ if (!folderPath) {
+ continue;
+ }
+
+ let dataFolderPath = join(folderPath.replace((wsPath || ''), ''));
+ if (dataFolderPath.startsWith('/')) {
+ dataFolderPath = dataFolderPath.substring(1);
+ }
+
+ const dataJsonFiles = await workspace.findFiles(join(dataFolderPath, '*.json'));
+ const dataYmlFiles = await workspace.findFiles(join(dataFolderPath, '*.yml'));
+ const dataYamlFiles = await workspace.findFiles(join(dataFolderPath, '*.yaml'));
+
+ const dataFiles = [...dataJsonFiles, ...dataYmlFiles, ...dataYamlFiles];
+ for (let dataFile of dataFiles) {
+ clonedFiles.push({
+ id: basename(dataFile.fsPath),
+ title: basename(dataFile.fsPath),
+ file: dataFile.fsPath,
+ fileType: dataFile.fsPath.endsWith('.json') ? 'json' : 'yaml',
+ labelField: folder.labelField,
+ schema: folder.schema,
+ type: folder.type
+ } as DataFile)
+ }
+ }
+ }
+
+ return clonedFiles;
+ }
}
\ No newline at end of file
diff --git a/src/helpers/Logger.ts b/src/helpers/Logger.ts
index 576a769e..18de1796 100644
--- a/src/helpers/Logger.ts
+++ b/src/helpers/Logger.ts
@@ -25,4 +25,12 @@ export class Logger {
Logger.channel?.appendLine(`["${type}" - ${format(new Date(), "HH:MM:ss")}] ${message}`);
}
+
+ public static warning(message: string): void {
+ Logger.info(message, "WARNING");
+ }
+
+ public static error(message: string): void {
+ Logger.info(message, "ERROR");
+ }
}
\ No newline at end of file
diff --git a/src/helpers/MediaHelpers.ts b/src/helpers/MediaHelpers.ts
index c0e69416..16c7eb69 100644
--- a/src/helpers/MediaHelpers.ts
+++ b/src/helpers/MediaHelpers.ts
@@ -10,6 +10,7 @@ import { commands, Uri, workspace, window, Position } from "vscode";
import imageSize from "image-size";
import { EditorHelper } from "@estruyf/vscode";
import { ExplorerView } from "../explorerView/ExplorerView";
+import { SortOption } from "../dashboardWebView/constants/SortOption";
export class MediaHelpers {
@@ -91,20 +92,7 @@ export class MediaHelpers {
}
}
- if (crntSort?.type === SortType.string) {
- allMedia = allMedia.sort(Sorting.alphabetically("fsPath"));
- } else if (crntSort?.type === SortType.date) {
- allMedia = allMedia.sort(Sorting.dateWithFallback("mtime", "fsPath"));
- } else {
- allMedia = allMedia.sort(Sorting.alphabetically("fsPath"));
- }
-
- if (crntSort?.order === SortOrder.desc) {
- allMedia = allMedia.reverse();
- }
-
MediaHelpers.media = Object.assign([], allMedia);
-
let files: MediaInfo[] = MediaHelpers.media;
// Retrieve the total after filtering and before the slicing happens
@@ -126,6 +114,27 @@ export class MediaHelpers {
});
files = files.filter(f => f.mtime !== undefined);
+ // Sort the files
+ if (crntSort?.type === SortType.string) {
+ if (crntSort.id === SortOption.AltAsc || crntSort.id === SortOption.AltDesc) {
+ files = files.sort(Sorting.alphabetically("alt"));
+ } else if (crntSort.id === SortOption.CaptionAsc || crntSort.id === SortOption.CaptionDesc) {
+ files = files.sort(Sorting.alphabetically("caption"));
+ } else {
+ files = files.sort(Sorting.alphabetically("fsPath"));
+ }
+ } else if (crntSort?.type === SortType.number && (crntSort?.id === SortOption.SizeAsc || crntSort?.id === SortOption.SizeDesc)) {
+ files = files.sort(Sorting.numerically("size"));
+ } else if (crntSort?.type === SortType.date) {
+ files = files.sort(Sorting.dateWithFallback("mtime", "fsPath"));
+ } else {
+ files = files.sort(Sorting.alphabetically("fsPath"));
+ }
+
+ if (crntSort?.order === SortOrder.desc) {
+ files = files.reverse();
+ }
+
// Retrieve all the folders
let allContentFolders: string[] = [];
let allFolders: string[] = [];
@@ -295,7 +304,7 @@ export class MediaHelpers {
panel.getMediaSelection();
} else {
panel.getMediaSelection();
- panel.updateMetadata({field: data.fieldName, value: data.image });
+ panel.updateMetadata({field: data.fieldName, value: data.image, parents: data.parents });
}
}
}
diff --git a/src/helpers/SlugHelper.ts b/src/helpers/SlugHelper.ts
index 70ffc0a7..7de5ca97 100644
--- a/src/helpers/SlugHelper.ts
+++ b/src/helpers/SlugHelper.ts
@@ -13,7 +13,7 @@ export class SlugHelper {
}
// Remove punctuation from input string, and split it into words.
- let cleanTitle = this.removePunctuation(articleTitle);
+ let cleanTitle = this.removePunctuation(articleTitle).trim();
if (cleanTitle) {
cleanTitle = cleanTitle.toLowerCase();
// Split into words
diff --git a/src/helpers/Sorting.ts b/src/helpers/Sorting.ts
index fdd6de87..ba514b50 100644
--- a/src/helpers/Sorting.ts
+++ b/src/helpers/Sorting.ts
@@ -20,6 +20,17 @@ export class Sorting {
};
};
+ /**
+ * Sort field value numerically
+ * @param property
+ * @returns
+ */
+ public static numerically = (property: string) => {
+ return (a: any, b: any) => {
+ return a[property] - b[property];
+ };
+ }
+
/**
* Sort by date
* @param property
diff --git a/src/helpers/TomlEngine.ts b/src/helpers/TomlEngine.ts
index 99839e6d..be0f4d97 100644
--- a/src/helpers/TomlEngine.ts
+++ b/src/helpers/TomlEngine.ts
@@ -11,7 +11,7 @@ export const getFormatOpts = (format: string): { language: string, delimiters: s
const formats: { [prop: string]: { language: string, delimiters: string | [string, string] | undefined }} = {
yaml: { language: 'yaml', delimiters: '---' },
toml: { language: 'toml', delimiters: '+++' },
- json: { language: 'json', delimiters: ['{', '}'] },
+ json: { language: 'json', delimiters: '---' },
};
return formats[format];
diff --git a/src/helpers/isValidFile.ts b/src/helpers/isValidFile.ts
index 3e2e874f..80ebdf4c 100644
--- a/src/helpers/isValidFile.ts
+++ b/src/helpers/isValidFile.ts
@@ -1,7 +1,15 @@
+import { DEFAULT_FILE_TYPES } from './../constants/DefaultFileTypes';
+import { Settings } from ".";
+import { SETTINGS_CONTENT_SUPPORTED_FILETYPES } from "../constants";
+import { extname } from 'path';
export const isValidFile = (fileName: string) => {
- return fileName.endsWith(`.md`) ||
- fileName.endsWith(`.markdown`) ||
- fileName.endsWith(`.mdx`);
+ let supportedFiles = Settings.get(SETTINGS_CONTENT_SUPPORTED_FILETYPES) || DEFAULT_FILE_TYPES;
+ supportedFiles = supportedFiles.map(f => f.startsWith(`.`) ? f : `.${f}`);
+
+ // Get the extension of the file path
+ const extension = extname(fileName);
+
+ return supportedFiles.includes(extension);
}
\ No newline at end of file
diff --git a/src/listeners/DataListener.ts b/src/listeners/DataListener.ts
new file mode 100644
index 00000000..7cc42c91
--- /dev/null
+++ b/src/listeners/DataListener.ts
@@ -0,0 +1,94 @@
+import { DataFile } from './../models/DataFile';
+import { DashboardMessage } from "../dashboardWebView/DashboardMessage";
+import { BaseListener } from "./BaseListener";
+import { DashboardCommand } from '../dashboardWebView/DashboardCommand';
+import { Folders } from '../commands/Folders';
+import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
+import { dirname } from 'path';
+import * as yaml from 'js-yaml';
+import { Logger, Notifications } from '../helpers';
+import { commands } from 'vscode';
+
+
+export class DataListener extends BaseListener {
+
+ public static process(msg: { command: DashboardMessage, data: any }) {
+ super.process(msg);
+
+ switch(msg.command) {
+ case (DashboardMessage.getDataEntries):
+ if (!(msg?.data as DataFile).file) {
+ this.sendMsg(DashboardCommand.dataFileEntries, []);
+ }
+
+ this.processDataFile(msg?.data);
+ break;
+ case (DashboardMessage.putDataEntries):
+ this.processDataUpdate(msg?.data);
+ break;
+ default:
+ return;
+ }
+ }
+
+ private static processDataUpdate(msgData: any) {
+ const { file, fileType, entries } = msgData as { file: string, fileType: string, entries: any[] };
+
+ const absPath = Folders.getAbsFilePath(file);
+ if (!existsSync(absPath)) {
+ const dirPath = dirname(absPath);
+ if (!existsSync(dirPath)) {
+ mkdirSync(dirPath, { recursive: true });
+ }
+ }
+
+ if (fileType === 'yaml') {
+ const yamlData = yaml.safeDump(entries);
+ writeFileSync(absPath, yamlData, 'utf8');
+ } else {
+ writeFileSync(absPath, JSON.stringify(entries, null, 2));
+ }
+
+ this.processDataFile(msgData);
+ }
+
+ /**
+ * Process the file data
+ * @param msgData
+ */
+ private static async processDataFile(msgData: DataFile) {
+ try {
+ const { file } = msgData;
+ const dataFile = this.getDataFile(file);
+
+ if (msgData.fileType === "yaml") {
+ const entries = yaml.safeLoad(dataFile || "");
+ this.sendMsg(DashboardCommand.dataFileEntries, entries);
+ } else {
+ const jsonData = dataFile ? JSON.parse(dataFile) : [];
+ this.sendMsg(DashboardCommand.dataFileEntries, jsonData);
+ }
+ } catch (ex) {
+ Logger.error((ex as Error).message);
+ const btnClick = await Notifications.error(`Something went wrong while processing the data file. Check your file and output log for more information.`, 'Open output');
+
+ if (btnClick && btnClick === 'Open output') {
+ commands.executeCommand(`workbench.panel.output.focus`);
+ }
+ }
+ }
+
+ /**
+ * Retrieve the file data
+ * @param file
+ * @returns
+ */
+ private static getDataFile(file: string) {
+ const absPath = Folders.getAbsFilePath(file);
+ if (existsSync(absPath)) {
+ return readFileSync(absPath, 'utf8');
+ }
+
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/src/listeners/MediaListener.ts b/src/listeners/MediaListener.ts
index 1640dbec..f85dcaa8 100644
--- a/src/listeners/MediaListener.ts
+++ b/src/listeners/MediaListener.ts
@@ -3,8 +3,9 @@ import { DashboardMessage } from "../dashboardWebView/DashboardMessage";
import { BaseListener } from "./BaseListener";
import { DashboardCommand } from '../dashboardWebView/DashboardCommand';
import { SortingOption } from '../dashboardWebView/models';
-import { commands } from 'vscode';
+import { commands, env, Uri } from 'vscode';
import { COMMAND_NAME } from '../constants';
+import * as os from 'os';
export class MediaListener extends BaseListener {
@@ -28,6 +29,9 @@ export class MediaListener extends BaseListener {
case DashboardMessage.deleteMedia:
this.delete(msg?.data);
break;
+ case DashboardMessage.revealMedia:
+ this.openFileInFinder(msg?.data?.file);
+ break;
case DashboardMessage.insertPreviewImage:
MediaHelpers.insertMediaToMarkdown(msg?.data);
break;
@@ -51,6 +55,16 @@ export class MediaListener extends BaseListener {
this.sendMsg(DashboardCommand.media, files);
}
+ private static openFileInFinder(file: string) {
+ if (file) {
+ if (os.type() === "Linux" && env.remoteName?.toLowerCase() === "wsl") {
+ commands.executeCommand('remote-wsl.revealInExplorer', Uri.parse(file));
+ } else {
+ commands.executeCommand('revealFileInOS', Uri.parse(file));
+ }
+ }
+ }
+
/**
* Store the file and send a message after multiple uploads
* @param data
diff --git a/src/listeners/PagesListener.ts b/src/listeners/PagesListener.ts
index 94e71b07..f77ddc85 100644
--- a/src/listeners/PagesListener.ts
+++ b/src/listeners/PagesListener.ts
@@ -1,6 +1,6 @@
import { isValidFile } from './../helpers/isValidFile';
import { existsSync } from "fs";
-import { dirname, join } from "path";
+import { basename, dirname, join } from "path";
import { commands, FileSystemWatcher, RelativePattern, Uri, workspace } from "vscode";
import { Dashboard } from "../commands/Dashboard";
import { Folders } from "../commands/Folders";
@@ -8,7 +8,7 @@ import { COMMAND_NAME, DefaultFields, SETTINGS_CONTENT_STATIC_FOLDER, SETTING_DA
import { DashboardCommand } from "../dashboardWebView/DashboardCommand";
import { DashboardMessage } from "../dashboardWebView/DashboardMessage";
import { Page } from "../dashboardWebView/models";
-import { ArticleHelper, Settings } from "../helpers";
+import { ArticleHelper, Logger, Settings } from "../helpers";
import { ContentType } from "../helpers/ContentType";
import { DateHelper } from "../helpers/DateHelper";
import { Notifications } from "../helpers/Notifications";
@@ -17,6 +17,7 @@ import { BaseListener } from "./BaseListener";
export class PagesListener extends BaseListener {
private static watchers: { [path: string]: FileSystemWatcher } = {};
+ private static lastPages: Page[] = [];
/**
* Start watching the folders in the current workspace for content changes
@@ -39,9 +40,10 @@ export class PagesListener extends BaseListener {
// Recreate all the watchers
for (const folder of folders) {
const folderUri = Uri.parse(folder.path);
- let watcher = workspace.createFileSystemWatcher(new RelativePattern(folderUri, "*"));
- watcher.onDidCreate(async (uri: Uri) => this.getPagesData);
- watcher.onDidDelete(async (uri: Uri) => this.getPagesData);
+ let watcher = workspace.createFileSystemWatcher(new RelativePattern(folderUri, "*"), false, false, false);
+ watcher.onDidCreate(async (uri: Uri) => this.watcherExec(uri));
+ watcher.onDidChange(async (uri: Uri) => this.watcherExec(uri));
+ watcher.onDidDelete(async (uri: Uri) => this.watcherExec(uri));
this.watchers[folderUri.fsPath] = watcher;
}
}
@@ -69,16 +71,29 @@ export class PagesListener extends BaseListener {
}
}
+ private static async watcherExec(file: Uri) {
+ if (Dashboard.isOpen) {
+ Logger.info(`File watcher execution for: ${file.fsPath}`)
+
+ const pageIdx = this.lastPages.findIndex(p => p.fmFilePath === file.fsPath);
+ if (pageIdx !== -1) {
+ const stats = await workspace.fs.stat(file);
+ const crntPage = this.lastPages[pageIdx];
+ const updatedPage = this.processPageContent(file.fsPath, stats.mtime, basename(file.fsPath), crntPage.fmFolder);
+ if (updatedPage) {
+ this.lastPages[pageIdx] = updatedPage;
+ this.sendMsg(DashboardCommand.pages, this.lastPages);
+ }
+ } else {
+ this.getPagesData();
+ }
+ }
+ }
+
/**
* Retrieve all the markdown pages
*/
private static async getPagesData() {
- const wsFolder = Folders.getWorkspaceFolder();
-
- const descriptionField = Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string || DefaultFields.Description;
- const dateField = Settings.get(SETTING_DATE_FIELD) as string || DefaultFields.PublishingDate;
- const staticFolder = Settings.get(SETTINGS_CONTENT_STATIC_FOLDER);
-
const folderInfo = await Folders.getInfo();
const pages: Page[] = [];
@@ -87,62 +102,12 @@ export class PagesListener extends BaseListener {
for (const file of folder.lastModified) {
if (isValidFile(file.fileName)) {
try {
- const article = ArticleHelper.getFrontMatterByPath(file.filePath);
+ const page = this.processPageContent(file.filePath, file.mtime, file.fileName, folder.title);
- if (article?.data.title) {
- const page: Page = {
- ...article.data,
- // FrontMatter properties
- fmFolder: folder.title,
- fmModified: file.mtime,
- fmFilePath: file.filePath,
- fmFileName: file.fileName,
- fmDraft: ContentType.getDraftStatus(article?.data),
- fmYear: article?.data[dateField] ? DateHelper.tryParse(article?.data[dateField])?.getFullYear() : null,
- // Make sure these are always set
- title: article?.data.title,
- slug: article?.data.slug,
- date: article?.data[dateField] || "",
- draft: article?.data.draft,
- description: article?.data[descriptionField] || "",
- };
-
- const contentType = ArticleHelper.getContentType(article.data);
- const previewField = contentType.fields.find(field => field.isPreviewImage && field.type === "image")?.name || "preview";
-
- if (article?.data[previewField] && wsFolder) {
- let fieldValue = article?.data[previewField];
- if (fieldValue && Array.isArray(fieldValue)) {
- if (fieldValue.length > 0) {
- fieldValue = fieldValue[0];
- } else {
- fieldValue = undefined;
- }
- }
-
- // Revalidate as the array could have been empty
- if (fieldValue) {
- const staticPath = join(wsFolder.fsPath, staticFolder || "", fieldValue);
- const contentFolderPath = join(dirname(file.filePath), fieldValue);
-
- let previewUri = null;
- if (existsSync(staticPath)) {
- previewUri = Uri.file(staticPath);
- } else if (existsSync(contentFolderPath)) {
- previewUri = Uri.file(contentFolderPath);
- }
-
- if (previewUri) {
- const preview = Dashboard.getWebview()?.asWebviewUri(previewUri);
- page[previewField] = preview?.toString() || "";
- } else {
- page[previewField] = "";
- }
- }
- }
-
+ if (page) {
pages.push(page);
}
+
} catch (error: any) {
Notifications.error(`File error: ${file.filePath} - ${error?.message || error}`);
}
@@ -151,10 +116,85 @@ export class PagesListener extends BaseListener {
}
}
+ this.lastPages = pages;
this.sendMsg(DashboardCommand.pages, pages);
}
public static refresh() {
this.getPagesData();
}
+
+ /**
+ * Process the page content
+ * @param filePath
+ * @param fileMtime
+ * @param fileName
+ * @param folderTitle
+ * @returns
+ */
+ private static processPageContent(filePath: string, fileMtime: number, fileName: string, folderTitle: string): Page | undefined {
+ const article = ArticleHelper.getFrontMatterByPath(filePath);
+
+ if (article?.data.title) {
+ const wsFolder = Folders.getWorkspaceFolder();
+ const descriptionField = Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string || DefaultFields.Description;
+ const dateField = Settings.get(SETTING_DATE_FIELD) as string || DefaultFields.PublishingDate;
+ const staticFolder = Settings.get(SETTINGS_CONTENT_STATIC_FOLDER);
+
+ const page: Page = {
+ ...article.data,
+ // FrontMatter properties
+ fmFolder: folderTitle,
+ fmModified: fileMtime,
+ fmFilePath: filePath,
+ fmFileName: fileName,
+ fmDraft: ContentType.getDraftStatus(article?.data),
+ fmYear: article?.data[dateField] ? DateHelper.tryParse(article?.data[dateField])?.getFullYear() : null,
+ // Make sure these are always set
+ title: article?.data.title,
+ slug: article?.data.slug,
+ date: article?.data[dateField] || "",
+ draft: article?.data.draft,
+ description: article?.data[descriptionField] || "",
+ };
+
+ const contentType = ArticleHelper.getContentType(article.data);
+ const previewField = contentType.fields.find(field => field.isPreviewImage && field.type === "image")?.name || "preview";
+
+ if (article?.data[previewField] && wsFolder) {
+ let fieldValue = article?.data[previewField];
+ if (fieldValue && Array.isArray(fieldValue)) {
+ if (fieldValue.length > 0) {
+ fieldValue = fieldValue[0];
+ } else {
+ fieldValue = undefined;
+ }
+ }
+
+ // Revalidate as the array could have been empty
+ if (fieldValue) {
+ const staticPath = join(wsFolder.fsPath, staticFolder || "", fieldValue);
+ const contentFolderPath = join(dirname(filePath), fieldValue);
+
+ let previewUri = null;
+ if (existsSync(staticPath)) {
+ previewUri = Uri.file(staticPath);
+ } else if (existsSync(contentFolderPath)) {
+ previewUri = Uri.file(contentFolderPath);
+ }
+
+ if (previewUri) {
+ const preview = Dashboard.getWebview()?.asWebviewUri(previewUri);
+ page[previewField] = preview?.toString() || "";
+ } else {
+ page[previewField] = "";
+ }
+ }
+ }
+
+ return page;
+ }
+
+ return;
+ }
}
\ No newline at end of file
diff --git a/src/models/CustomTaxonomyData.ts b/src/models/CustomTaxonomyData.ts
index ad0510db..f9b9f1b1 100644
--- a/src/models/CustomTaxonomyData.ts
+++ b/src/models/CustomTaxonomyData.ts
@@ -4,4 +4,5 @@ export interface CustomTaxonomyData {
name: string | undefined;
options?: string[] | undefined;
option?: string | undefined;
+ parents?: string[];
}
\ No newline at end of file
diff --git a/src/models/DashboardData.ts b/src/models/DashboardData.ts
index 27318fea..df0f8f93 100644
--- a/src/models/DashboardData.ts
+++ b/src/models/DashboardData.ts
@@ -1,4 +1,4 @@
export interface DashboardData {
- type: "contents" | "media";
+ type: "contents" | "media" | "data";
data?: any;
}
\ No newline at end of file
diff --git a/src/models/DataFile.ts b/src/models/DataFile.ts
new file mode 100644
index 00000000..48a375f6
--- /dev/null
+++ b/src/models/DataFile.ts
@@ -0,0 +1,9 @@
+export interface DataFile {
+ id: string;
+ title: string;
+ file: string;
+ fileType: "json" | "yaml";
+ labelField: string;
+ schema?: any;
+ type?: string;
+}
\ No newline at end of file
diff --git a/src/models/DataFolder.ts b/src/models/DataFolder.ts
new file mode 100644
index 00000000..20337ed2
--- /dev/null
+++ b/src/models/DataFolder.ts
@@ -0,0 +1,9 @@
+
+
+export interface DataFolder {
+ id: string;
+ path: string;
+ labelField: string;
+ schema?: any;
+ type?: string;
+}
\ No newline at end of file
diff --git a/src/models/DataType.ts b/src/models/DataType.ts
new file mode 100644
index 00000000..4469a1f1
--- /dev/null
+++ b/src/models/DataType.ts
@@ -0,0 +1,4 @@
+export interface DataType {
+ id: string;
+ schema: any;
+}
\ No newline at end of file
diff --git a/src/models/PanelSettings.ts b/src/models/PanelSettings.ts
index 942ed702..e64c2a9f 100644
--- a/src/models/PanelSettings.ts
+++ b/src/models/PanelSettings.ts
@@ -20,13 +20,20 @@ export interface PanelSettings {
contentTypes: ContentType[];
dashboardViewData: DashboardData | undefined;
draftField: DraftField;
+ isBacker: boolean | undefined;
+ framework: string | undefined;
+ commands: FrameworkCommands;
+}
+
+export interface FrameworkCommands {
+ start: string | undefined;
}
export interface ContentType {
name: string;
fields: Field[];
- fileType?: "md" | "mdx";
+ fileType?: "md" | "mdx" | string;
previewPath?: string | null;
pageBundle?: boolean;
}
@@ -34,13 +41,15 @@ export interface ContentType {
export interface Field {
title?: string;
name: string;
- type: "string" | "number" | "datetime" | "boolean" | "image" | "choice" | "tags" | "categories" | "draft" | "taxonomy";
+ type: "string" | "number" | "datetime" | "boolean" | "image" | "choice" | "tags" | "categories" | "draft" | "taxonomy" | "fields";
choices?: string[] | Choice[];
single?: boolean;
multiple?: boolean;
isPreviewImage?: boolean;
hidden?: boolean;
taxonomyId?: string;
+ default?: string;
+ fields?: Field[];
}
export interface DateInfo {
diff --git a/src/models/SortType.ts b/src/models/SortType.ts
index 78b308db..810f7667 100644
--- a/src/models/SortType.ts
+++ b/src/models/SortType.ts
@@ -1,4 +1,5 @@
export enum SortType {
string = 'string',
+ number = 'number',
date = 'date'
}
\ No newline at end of file
diff --git a/src/panelWebView/CommandToCode.ts b/src/panelWebView/CommandToCode.ts
index 339a9456..e55cf729 100644
--- a/src/panelWebView/CommandToCode.ts
+++ b/src/panelWebView/CommandToCode.ts
@@ -28,4 +28,6 @@ export enum CommandToCode {
selectImage = "select-image",
updateCustomTaxonomy = "updateCustomTaxonomy",
addToCustomTaxonomy = "addToCustomTaxonomy",
+ frameworkCommand = "framework-command",
+ updateStartCommand = "update-start-command",
}
\ No newline at end of file
diff --git a/src/panelWebView/ViewPanel.tsx b/src/panelWebView/ViewPanel.tsx
index fdcab7da..201a9c1b 100644
--- a/src/panelWebView/ViewPanel.tsx
+++ b/src/panelWebView/ViewPanel.tsx
@@ -59,7 +59,7 @@ export const ViewPanel: React.FunctionComponent = (props: React
-
+
);
};
\ No newline at end of file
diff --git a/src/panelWebView/components/Actions.tsx b/src/panelWebView/components/Actions.tsx
index ac5454f3..7997fcfd 100644
--- a/src/panelWebView/components/Actions.tsx
+++ b/src/panelWebView/components/Actions.tsx
@@ -4,14 +4,14 @@ import { Collapsible } from './Collapsible';
import { CustomScript } from './CustomScript';
import { Preview } from './Preview';
import { SlugAction } from './SlugAction';
+import { StartServerButton } from './StartServerButton';
export interface IActionsProps {
metadata: any;
settings: PanelSettings;
}
-const Actions: React.FunctionComponent = (props: React.PropsWithChildren) => {
- const { metadata, settings } = props;
+const Actions: React.FunctionComponent = ({ metadata, settings }: React.PropsWithChildren) => {
if (!metadata || Object.keys(metadata).length === 0 || !settings) {
return null;
@@ -21,10 +21,12 @@ const Actions: React.FunctionComponent = (props: React.PropsWithC
- { metadata && metadata.title &&
}
+ { metadata && metadata.title &&
}
{ settings?.preview?.host &&
}
+
+
{
(settings && settings.scripts && settings.scripts.length > 0) && (
settings.scripts.map((value, idx) => (
diff --git a/src/panelWebView/components/BaseView.tsx b/src/panelWebView/components/BaseView.tsx
index 17c0a51a..ad8d6003 100644
--- a/src/panelWebView/components/BaseView.tsx
+++ b/src/panelWebView/components/BaseView.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { FolderInfo, PanelSettings } from '../../models';
+import { CustomScript, FolderInfo, PanelSettings } from '../../models';
import { CommandToCode } from '../CommandToCode';
import { MessageHelper } from '../../helpers/MessageHelper';
import { Collapsible } from './Collapsible';
@@ -7,6 +7,7 @@ import { GlobalSettings } from './GlobalSettings';
import { OtherActions } from './OtherActions';
import { FolderAndFiles } from './FolderAndFiles';
import { SponsorMsg } from './SponsorMsg';
+import { StartServerButton } from './StartServerButton';
export interface IBaseViewProps {
settings: PanelSettings | undefined;
@@ -31,6 +32,12 @@ const BaseView: React.FunctionComponent
= ({settings, folderAndF
MessageHelper.sendMessage(CommandToCode.openPreview);
};
+ const runBulkScript = (script: CustomScript) => {
+ MessageHelper.sendMessage(CommandToCode.runCustomScript, { title: script.title, script });
+ };
+
+ const customActions: any[] = (settings?.scripts || []).filter(s => s.bulk && (s.type === "content" || !s.type));
+
return (
@@ -39,9 +46,15 @@ const BaseView: React.FunctionComponent
= ({settings, folderAndF
Open dashboard
+
Initialize project
Create new content
Open site preview
+ {
+ customActions.map((script) => (
+ runBulkScript(script)}>{ script.title }
+ ))
+ }
@@ -50,7 +63,7 @@ const BaseView: React.FunctionComponent = ({settings, folderAndF
-
+
);
};
diff --git a/src/panelWebView/components/Fields/ChoiceField.tsx b/src/panelWebView/components/Fields/ChoiceField.tsx
index 317c68dd..3727c5d2 100644
--- a/src/panelWebView/components/Fields/ChoiceField.tsx
+++ b/src/panelWebView/components/Fields/ChoiceField.tsx
@@ -83,7 +83,7 @@ export const ChoiceField: React.FunctionComponent = ({label,
onValueChange(selected || "")}
+ onSelect={(selected) => onValueChange(selected || "")}
itemToString={item => (item ? item : '')}>
{({ getToggleButtonProps, getItemProps, getMenuProps, isOpen, getRootProps }) => (
diff --git a/src/panelWebView/components/Fields/PreviewImageField.tsx b/src/panelWebView/components/Fields/PreviewImageField.tsx
index c1f41899..11100645 100644
--- a/src/panelWebView/components/Fields/PreviewImageField.tsx
+++ b/src/panelWebView/components/Fields/PreviewImageField.tsx
@@ -15,18 +15,21 @@ export interface IPreviewImageFieldProps {
fieldName: string;
value: PreviewImageValue | PreviewImageValue[] | null;
filePath: string | null;
+ parents?: string[];
multiple?: boolean;
onChange: (value: string | string[] | null) => void;
}
-export const PreviewImageField: React.FunctionComponent = ({label, fieldName, onChange, value, filePath, multiple}: React.PropsWithChildren) => {
+export const PreviewImageField: React.FunctionComponent = ({label, fieldName, onChange, value, filePath, multiple, parents}: React.PropsWithChildren) => {
const selectImage = () => {
MessageHelper.sendMessage(CommandToCode.selectImage, {
filePath: filePath,
fieldName,
value,
- multiple
+ multiple,
+ metadataInsert: true,
+ parents
});
};
diff --git a/src/panelWebView/components/FileItem.tsx b/src/panelWebView/components/FileItem.tsx
index 08cd2544..899e84a4 100644
--- a/src/panelWebView/components/FileItem.tsx
+++ b/src/panelWebView/components/FileItem.tsx
@@ -1,5 +1,5 @@
import * as React from 'react';
-import { isValidFile } from '../../helpers/isValidFile';
+import { DEFAULT_FILE_TYPES } from '../../constants/DefaultFileTypes';
import { MessageHelper } from '../../helpers/MessageHelper';
import { CommandToCode } from '../CommandToCode';
import { FileIcon } from './Icons/FileIcon';
@@ -16,11 +16,14 @@ const FileItem: React.FunctionComponent = ({ name, path }: React
MessageHelper.sendMessage(CommandToCode.openInEditor, path);
};
+ // File extension
+ const fileExtension = `.${name.split('.').pop()}`;
+
return (
{
- (isValidFile(name)) ? (
+ (DEFAULT_FILE_TYPES.includes(fileExtension)) ? (
) : (
diff --git a/src/panelWebView/components/GlobalSettings.tsx b/src/panelWebView/components/GlobalSettings.tsx
index fe503b15..ddcfce9b 100644
--- a/src/panelWebView/components/GlobalSettings.tsx
+++ b/src/panelWebView/components/GlobalSettings.tsx
@@ -5,6 +5,7 @@ import { MessageHelper } from '../../helpers/MessageHelper';
import { useDebounce } from '../../hooks/useDebounce';
import { Collapsible } from './Collapsible';
import { VsCheckbox, VsLabel } from './VscodeComponents';
+import useStartCommand from '../hooks/useStartCommand';
export interface IGlobalSettingsProps {
settings: PanelSettings | undefined;
@@ -14,7 +15,11 @@ export interface IGlobalSettingsProps {
const GlobalSettings: React.FunctionComponent = ({settings, isBase}: React.PropsWithChildren) => {
const { modifiedDateUpdate, fmHighlighting } = settings || {};
const [ previewUrl, setPreviewUrl ] = React.useState("");
+ const [ startCommandValue, setStartCommandValue ] = React.useState(null);
const [ isDirty, setIsDirty ] = React.useState(false);
+ const { startCommand } = useStartCommand(settings);
+
+ const debounceStartCommand = useDebounce(startCommandValue, 1000);
const debouncePreviewUrl = useDebounce(previewUrl, 1000);
const onDateCheck = () => {
@@ -30,12 +35,21 @@ const GlobalSettings: React.FunctionComponent = ({settings
setPreviewUrl(e.currentTarget.value);
};
+ const updateStartCommand = (e: React.ChangeEvent) => {
+ setIsDirty(true);
+ setStartCommandValue(e.currentTarget.value);
+ };
+
React.useEffect(() => {
if (settings?.preview.host) {
setPreviewUrl(settings.preview.host);
}
}, [settings?.preview.host]);
+ React.useEffect(() => {
+ setStartCommandValue(startCommand);
+ }, [startCommand]);
+
React.useEffect(() => {
if (isDirty) {
setIsDirty(false);
@@ -43,6 +57,13 @@ const GlobalSettings: React.FunctionComponent = ({settings
}
}, [debouncePreviewUrl]);
+ React.useEffect(() => {
+ if (isDirty) {
+ setIsDirty(false);
+ MessageHelper.sendMessage(CommandToCode.updateStartCommand, debounceStartCommand);
+ }
+ }, [debounceStartCommand]);
+
return (
<>
@@ -62,6 +83,14 @@ const GlobalSettings: React.FunctionComponent = ({settings
value={previewUrl}
onChange={previewChange} />
+
+ Local server command
+
+
>
);
diff --git a/src/panelWebView/components/Metadata.tsx b/src/panelWebView/components/Metadata.tsx
index 230325e6..a6994840 100644
--- a/src/panelWebView/components/Metadata.tsx
+++ b/src/panelWebView/components/Metadata.tsx
@@ -19,10 +19,14 @@ import useContentType from '../../hooks/useContentType';
import { DateHelper } from '../../helpers/DateHelper';
import FieldBoundary from './ErrorBoundary/FieldBoundary';
import { DraftField } from './Fields/DraftField';
+import { VsLabel } from './VscodeComponents';
+export interface IMetadata {
+ [prop: string]: string[] | string | null | IMetadata;
+}
export interface IMetadataProps {
settings: PanelSettings | undefined;
- metadata: { [prop: string]: string[] | string | null };
+ metadata: IMetadata;
focusElm: TagType | null;
unsetFocus: () => void;
}
@@ -30,13 +34,14 @@ export interface IMetadataProps {
const Metadata: React.FunctionComponent = ({settings, metadata, focusElm, unsetFocus}: React.PropsWithChildren) => {
const contentType = useContentType(settings, metadata);
- const sendUpdate = (field: string | undefined, value: any) => {
+ const sendUpdate = (field: string | undefined, value: any, parents: string[]) => {
if (!field) {
return;
}
MessageHelper.sendMessage(CommandToCode.updateMetadata, {
field,
+ parents,
value
});
};
@@ -50,7 +55,7 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
return null;
}
- const renderFields = (ctFields: Field[]) => {
+ const renderFields = (ctFields: Field[], parent: IMetadata, parentFields: string[] = []) => {
if (!ctFields) {
return;
}
@@ -61,7 +66,7 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
}
if (field.type === 'datetime') {
- const dateValue = metadata[field.name] ? getDate(metadata[field.name] as string) : null;
+ const dateValue = parent[field.name] ? getDate(parent[field.name] as string) : null;
return (
@@ -69,7 +74,7 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
label={field.title || field.name}
date={dateValue}
format={settings?.date?.format}
- onChange={(date => sendUpdate(field.name, date))} />
+ onChange={(date => sendUpdate(field.name, date, parentFields))} />
);
} else if (field.type === 'boolean') {
@@ -78,12 +83,12 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
sendUpdate(field.name, checked)} />
+ checked={!!parent[field.name] as any}
+ onChanged={(checked) => sendUpdate(field.name, checked, parentFields)} />
);
} else if (field.type === 'string') {
- const textValue = metadata[field.name];
+ const textValue = parent[field.name];
let limit = -1;
if (field.name === 'title') {
@@ -99,12 +104,12 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
singleLine={field.single}
limit={limit}
rows={3}
- onChange={(value) => sendUpdate(field.name, value)}
+ onChange={(value) => sendUpdate(field.name, value, parentFields)}
value={textValue as string || null} />
);
} else if (field.type === 'number') {
- const fieldValue = metadata[field.name];
+ const fieldValue = parent[field.name];
let nrValue: number | null = parseInt(fieldValue as string);
if (isNaN(nrValue)) {
nrValue = null;
@@ -115,7 +120,7 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
sendUpdate(field.name, value)}
+ onChange={(value) => sendUpdate(field.name, value, parentFields)}
value={nrValue} />
);
@@ -126,14 +131,15 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
label={field.title || field.name}
fieldName={field.name}
filePath={metadata.filePath as string}
- value={metadata[field.name] as PreviewImageValue | PreviewImageValue[] | null}
+ parents={parentFields}
+ value={parent[field.name] as PreviewImageValue | PreviewImageValue[] | null}
multiple={field.multiple}
- onChange={(value => sendUpdate(field.name, value))} />
+ onChange={(value) => sendUpdate(field.name, value, parentFields)} />
);
} else if (field.type === 'choice') {
const choices = field.choices || [];
- const choiceValue = metadata[field.name];
+ const choiceValue = parent[field.name];
return (
@@ -142,7 +148,7 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
selected={choiceValue as string}
choices={choices}
multiSelect={field.multiple}
- onChange={(value => sendUpdate(field.name, value))} />
+ onChange={(value => sendUpdate(field.name, value, parentFields))} />
);
} else if (field.type === 'tags') {
@@ -152,16 +158,17 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
type={TagType.tags}
label={field.title || field.name}
icon={ }
- crntSelected={metadata[field.name] as string[] || []}
+ crntSelected={parent[field.name] as string[] || []}
options={settings?.tags || []}
freeform={settings.freeform}
focussed={focusElm === TagType.tags}
- unsetFocus={unsetFocus} />
+ unsetFocus={unsetFocus}
+ parents={parentFields} />
);
} else if (field.type === 'taxonomy') {
const taxonomyData = settings.customTaxonomy.find(ct => ct.id === field.taxonomyId);
- const selectedValues = metadata[field.name] || [];
+ const selectedValues = parent[field.name] || [];
return (
@@ -175,7 +182,8 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
focussed={focusElm === TagType.custom}
unsetFocus={unsetFocus}
fieldName={field.name}
- taxonomyId={field.taxonomyId} />
+ taxonomyId={field.taxonomyId}
+ parents={parentFields} />
);
} else if (field.type === 'categories') {
@@ -185,16 +193,17 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
type={TagType.categories}
label={field.title || field.name}
icon={ }
- crntSelected={metadata.categories as string[] || []}
+ crntSelected={parent.categories as string[] || []}
options={settings.categories}
freeform={settings.freeform}
focussed={focusElm === TagType.categories}
- unsetFocus={unsetFocus} />
+ unsetFocus={unsetFocus}
+ parents={parentFields} />
);
} else if (field.type === 'draft') {
const draftField = settings?.draftField;
- const value = metadata[field.name];
+ const value = parent[field.name];
return (
@@ -203,9 +212,28 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
type={draftField.type}
choices={draftField.choices || []}
value={value as boolean | string | null | undefined}
- onChanged={(value: boolean | string) => sendUpdate(field.name, value)} />
+ onChanged={(value: boolean | string) => sendUpdate(field.name, value, parentFields)} />
);
+ } else if (field.type === 'fields') {
+ if (field.fields && parent && parent[field.name]) {
+ const subMetadata = parent[field.name] as IMetadata;
+ return (
+
+
+
+
+ {field.title || field.name}
+
+
+
+ { renderFields(field.fields, subMetadata, [...parentFields, field.name]) }
+
+
+ );
+ }
+
+ return null;
} else {
return null;
}
@@ -214,9 +242,9 @@ const Metadata: React.FunctionComponent = ({settings, metadata,
return (
-
+
{
- renderFields(contentType?.fields)
+ renderFields(contentType?.fields, metadata)
}
{
diff --git a/src/panelWebView/components/SeoKeywordInfo.tsx b/src/panelWebView/components/SeoKeywordInfo.tsx
index 1b27b641..148df429 100644
--- a/src/panelWebView/components/SeoKeywordInfo.tsx
+++ b/src/panelWebView/components/SeoKeywordInfo.tsx
@@ -33,12 +33,22 @@ const SeoKeywordInfo: React.FunctionComponent = ({keyword,
}
};
+ const validateKeywords = (heading: string, keyword: string) => {
+ const keywords = keyword.toLowerCase().split(' ');
+
+ if (keywords.length > 1) {
+ return heading.toLowerCase().includes(keyword.toLowerCase());
+ } else {
+ return heading.toLowerCase().split(' ').findIndex(word => word.toLowerCase() === keyword.toLowerCase()) !== -1;
+ }
+ };
+
const checkHeadings = () => {
if (!headings || headings.length === 0) {
return null;
}
-
- const exists = headings.filter(heading => heading.split(' ').findIndex(word => word.toLowerCase() === keyword.toLowerCase()) !== -1);
+
+ const exists = headings.filter(heading => validateKeywords(heading, keyword));
return 0} />;
};
diff --git a/src/panelWebView/components/SlugAction.tsx b/src/panelWebView/components/SlugAction.tsx
index 15967aad..c27fb888 100644
--- a/src/panelWebView/components/SlugAction.tsx
+++ b/src/panelWebView/components/SlugAction.tsx
@@ -1,28 +1,18 @@
import * as React from 'react';
import { MessageHelper } from '../../helpers/MessageHelper';
-import { SlugHelper } from '../../helpers/SlugHelper';
-import { Slug } from '../../models/PanelSettings';
import { CommandToCode } from '../CommandToCode';
import { ActionButton } from './ActionButton';
-export interface ISlugActionProps {
- value: string;
- crntValue: string;
- slugOpts: Slug;
-}
+export interface ISlugActionProps {}
-const SlugAction: React.FunctionComponent = (props: React.PropsWithChildren) => {
- const { value, crntValue, slugOpts } = props;
-
- let slug = SlugHelper.createSlug(value);
- slug = `${slugOpts.prefix}${slug}${slugOpts.suffix}`;
+const SlugAction: React.FunctionComponent = ({}: React.PropsWithChildren) => {
const optimize = () => {
MessageHelper.sendMessage(CommandToCode.updateSlug);
};
return (
-
+
);
};
diff --git a/src/panelWebView/components/SponsorMsg.tsx b/src/panelWebView/components/SponsorMsg.tsx
index 6001038b..d8456e0d 100644
--- a/src/panelWebView/components/SponsorMsg.tsx
+++ b/src/panelWebView/components/SponsorMsg.tsx
@@ -2,9 +2,15 @@ import * as React from 'react';
import { SPONSOR_LINK } from '../../constants/Links';
import { HeartIcon } from './Icons/HeartIcon';
-export interface ISponsorMsgProps {}
+export interface ISponsorMsgProps {
+ isBacker: boolean | undefined;
+}
+
+const SponsorMsg: React.FunctionComponent = ({ isBacker }: React.PropsWithChildren) => {
+ if (isBacker) {
+ return null;
+ }
-const SponsorMsg: React.FunctionComponent = (props: React.PropsWithChildren) => {
return (
diff --git a/src/panelWebView/components/StartServerButton.tsx b/src/panelWebView/components/StartServerButton.tsx
new file mode 100644
index 00000000..6ab35f20
--- /dev/null
+++ b/src/panelWebView/components/StartServerButton.tsx
@@ -0,0 +1,22 @@
+import * as React from 'react';
+import { FrameworkDetectors } from '../../constants/FrameworkDetectors';
+import { MessageHelper } from '../../helpers/MessageHelper';
+import { PanelSettings } from '../../models';
+import { CommandToCode } from '../CommandToCode';
+import useStartCommand from '../hooks/useStartCommand';
+
+export interface IStartServerButtonProps {
+ settings: PanelSettings | undefined;
+}
+
+export const StartServerButton: React.FunctionComponent = ({settings}: React.PropsWithChildren) => {
+ const { startCommand } = useStartCommand(settings);
+
+ const startLocalServer = (command: string) => {
+ MessageHelper.sendMessage(CommandToCode.frameworkCommand, { command });
+ };
+
+ return (
+ startCommand ? startLocalServer(startCommand)}>Start server : null
+ );
+};
\ No newline at end of file
diff --git a/src/panelWebView/components/TagPicker.tsx b/src/panelWebView/components/TagPicker.tsx
index 8e02b71d..3ce29307 100644
--- a/src/panelWebView/components/TagPicker.tsx
+++ b/src/panelWebView/components/TagPicker.tsx
@@ -12,19 +12,21 @@ import { CustomTaxonomyData } from '../../models';
export interface ITagPickerProps {
type: TagType;
icon: JSX.Element;
- label?: string;
crntSelected: string[];
options: string[];
freeform: boolean;
focussed: boolean;
unsetFocus: () => void;
+
+ parents?: string[];
+ label?: string;
disableConfigurable?: boolean;
fieldName?: string;
taxonomyId?: string;
}
const TagPicker: React.FunctionComponent = (props: React.PropsWithChildren) => {
- const { label, icon, type, crntSelected, options, freeform, focussed, unsetFocus, disableConfigurable, fieldName, taxonomyId } = props;
+ const { label, icon, type, crntSelected, options, freeform, focussed, unsetFocus, disableConfigurable, fieldName, taxonomyId, parents } = props;
const [ selected, setSelected ] = React.useState([]);
const [ inputValue, setInputValue ] = React.useState("");
const prevSelected = usePrevious(crntSelected);
@@ -65,16 +67,26 @@ const TagPicker: React.FunctionComponent = (props: React.PropsW
*/
const sendUpdate = (values: string[]) => {
if (type === TagType.tags) {
- MessageHelper.sendMessage(CommandToCode.updateTags, values);
+ MessageHelper.sendMessage(CommandToCode.updateTags, {
+ values,
+ parents
+ });
} else if (type === TagType.categories) {
- MessageHelper.sendMessage(CommandToCode.updateCategories, values);
+ MessageHelper.sendMessage(CommandToCode.updateCategories, {
+ values,
+ parents
+ });
} else if (type === TagType.keywords) {
- MessageHelper.sendMessage(CommandToCode.updateKeywords, values);
+ MessageHelper.sendMessage(CommandToCode.updateKeywords, {
+ values,
+ parents
+ });
} else if (type === TagType.custom) {
MessageHelper.sendMessage(CommandToCode.updateCustomTaxonomy, {
id: taxonomyId,
name: fieldName,
- options: values
+ options: values,
+ parents
} as CustomTaxonomyData);
}
};
diff --git a/src/panelWebView/hooks/useStartCommand.tsx b/src/panelWebView/hooks/useStartCommand.tsx
new file mode 100644
index 00000000..e8045393
--- /dev/null
+++ b/src/panelWebView/hooks/useStartCommand.tsx
@@ -0,0 +1,28 @@
+import { useState, useEffect } from 'react';
+import { FrameworkDetectors } from '../../constants/FrameworkDetectors';
+import { PanelSettings } from '../../models';
+
+export default function useStartCommand(settings?: PanelSettings) {
+ const [startCommand, setStartCommand] = useState(null);
+
+ useEffect(() => {
+ if (settings?.commands?.start) {
+ setStartCommand(settings?.commands?.start);
+ return;
+ }
+
+ let command: string = '';
+ if (settings?.framework) {
+ const framework = FrameworkDetectors.find(f => f.framework.name === settings.framework);
+ if (framework?.commands?.start) {
+ command = framework.commands.start;
+ }
+ }
+
+ setStartCommand(command);
+ }, [settings?.framework, settings?.commands?.start]);
+
+ return {
+ startCommand
+ };
+}
\ No newline at end of file
diff --git a/src/panelWebView/index.tsx b/src/panelWebView/index.tsx
index 4452e418..360f5120 100644
--- a/src/panelWebView/index.tsx
+++ b/src/panelWebView/index.tsx
@@ -18,23 +18,32 @@ import '@bendera/vscode-webview-elements/dist/vscode-checkbox.js';
// import '@vscode/webview-ui-toolkit/dist/esm/checkbox';
-const elm = document.querySelector("#app");
-const version = elm?.getAttribute("data-version");
-const environment = elm?.getAttribute("data-environment");
-
-Sentry.init({
- dsn: SENTRY_LINK,
- integrations: [new Integrations.BrowserTracing()],
- tracesSampleRate: 0, // No performance tracing required
- release: version || "",
- environment: environment || "",
- ignoreErrors: ['ResizeObserver loop limit exceeded']
-});
-
declare const acquireVsCodeApi: () => {
getState: () => T;
setState: (data: T) => void;
postMessage: (msg: unknown) => void;
};
-render( , elm);
+const elm = document.querySelector("#app");
+
+if (elm) {
+ const version = elm?.getAttribute("data-version");
+ const environment = elm?.getAttribute("data-environment");
+ const isProd = elm?.getAttribute("data-isProd");
+
+ if (isProd === "true") {
+ Sentry.init({
+ dsn: SENTRY_LINK,
+ integrations: [new Integrations.BrowserTracing()],
+ tracesSampleRate: 0, // No performance tracing required
+ release: version || "",
+ environment: environment || "",
+ ignoreErrors: ['ResizeObserver loop limit exceeded']
+ });
+ }
+
+ render( , elm);
+}
+
+// Webpack HMR
+if ((module as any).hot) (module as any).hot.accept();
\ No newline at end of file
diff --git a/src/providers/MarkdownFoldingProvider.ts b/src/providers/MarkdownFoldingProvider.ts
index f3e5e6e2..4d00e04f 100644
--- a/src/providers/MarkdownFoldingProvider.ts
+++ b/src/providers/MarkdownFoldingProvider.ts
@@ -1,6 +1,6 @@
import { TextEditorDecorationType } from 'vscode';
import { CancellationToken, FoldingContext, FoldingRange, FoldingRangeKind, FoldingRangeProvider, Range, TextDocument, window, Position } from 'vscode';
-import { SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT } from '../constants';
+import { SETTINGS_CONTENT_FRONTMATTER_HIGHLIGHT, SETTING_FRONTMATTER_TYPE } from '../constants';
import { Settings } from '../helpers';
import { FrontMatterDecorationProvider } from './FrontMatterDecorationProvider';
@@ -50,6 +50,15 @@ export class MarkdownFoldingProvider implements FoldingRangeProvider {
* @returns
*/
public static getFrontMatterRange(document?: TextDocument) {
+ const language = Settings.get(SETTING_FRONTMATTER_TYPE) as string || "YAML";
+
+ let lineStart = "---";
+ let lineEnd = "---";
+ if (language === "TOML") {
+ lineStart = "+++";
+ lineEnd = lineStart;
+ }
+
if (document) {
const lines = document.getText().split('\n');
@@ -59,7 +68,7 @@ export class MarkdownFoldingProvider implements FoldingRangeProvider {
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
- if (line.startsWith('---')) {
+ if (line.startsWith(lineStart) || line.startsWith(lineEnd)) {
if (i === 0 && start === null) {
start = i;
} else if (start !== null && end === null) {
diff --git a/src/services/Credentials.ts b/src/services/Credentials.ts
new file mode 100644
index 00000000..8e4d564c
--- /dev/null
+++ b/src/services/Credentials.ts
@@ -0,0 +1,69 @@
+import * as Octokit from '@octokit/rest';
+import { authentication, ExtensionContext } from 'vscode';
+
+const GITHUB_AUTH_PROVIDER_ID = 'github';
+// The GitHub Authentication Provider accepts the scopes described here:
+// https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/
+const SCOPES = ['user:email'];
+
+export class Credentials {
+ private octokit: Octokit.Octokit | undefined;
+
+ async initialize(context: ExtensionContext, callback: () => void): Promise {
+ this.registerListeners(context, callback);
+ this.setOctokit();
+ }
+
+ private async setOctokit() {
+ /**
+ * By passing the `createIfNone` flag, a numbered badge will show up on the accounts activity bar icon.
+ * An entry for the sample extension will be added under the menu to sign in. This allows quietly
+ * prompting the user to sign in.
+ * */
+ const session = await authentication.getSession(GITHUB_AUTH_PROVIDER_ID, SCOPES, { createIfNone: false });
+
+ if (session) {
+ this.octokit = new Octokit.Octokit({
+ auth: session.accessToken
+ });
+
+ return;
+ }
+
+ this.octokit = undefined;
+ }
+
+ registerListeners(context: ExtensionContext, callback: () => void): void {
+ /**
+ * Sessions are changed when a user logs in or logs out.
+ */
+ context.subscriptions.push(
+ authentication.onDidChangeSessions(async e => {
+ if (e.provider.id === GITHUB_AUTH_PROVIDER_ID) {
+ await this.setOctokit();
+
+ if (callback) {
+ callback();
+ }
+ }
+ })
+ );
+ }
+
+ async getOctokit(): Promise {
+ if (this.octokit) {
+ return this.octokit;
+ }
+
+ /**
+ * When the `createIfNone` flag is passed, a modal dialog will be shown asking the user to sign in.
+ * Note that this can throw if the user clicks cancel.
+ */
+ const session = await authentication.getSession(GITHUB_AUTH_PROVIDER_ID, SCOPES, { createIfNone: true });
+ this.octokit = new Octokit.Octokit({
+ auth: session.accessToken
+ });
+
+ return this.octokit;
+ }
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index c16f7952..47ede041 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -13,7 +13,8 @@
"sourceMap": true,
"rootDir": "src",
"strict": true,
- "jsx": "react"
+ "jsx": "react",
+ "strictNullChecks": true
},
"exclude": [
"node_modules",
diff --git a/webpack/dashboard.config.js b/webpack/dashboard.config.js
index 17bdd2e1..688ade97 100644
--- a/webpack/dashboard.config.js
+++ b/webpack/dashboard.config.js
@@ -38,13 +38,7 @@ const config = [
maxEntrypointSize: 400000,
maxAssetSize: 400000
},
- plugins: [
- new BundleAnalyzerPlugin({
- analyzerMode: 'static',
- reportFilename: "dashboard.html",
- openAnalyzer: false
- })
- ],
+ plugins: [],
devServer: {
compress: true,
port: 9000,
@@ -60,6 +54,14 @@ const config = [
module.exports = (env, argv) => {
for (const configItem of config) {
configItem.mode = argv.mode;
+
+ if (argv.mode === 'production') {
+ configItem.plugins.push(new BundleAnalyzerPlugin({
+ analyzerMode: 'static',
+ reportFilename: "dashboard.html",
+ openAnalyzer: false
+ }));
+ }
}
return config;
diff --git a/webpack/extension.config.js b/webpack/extension.config.js
index 5323f3bc..80b7b250 100644
--- a/webpack/extension.config.js
+++ b/webpack/extension.config.js
@@ -56,78 +56,21 @@ const config = [
}
}
},
- plugins: [
- new BundleAnalyzerPlugin({
- analyzerMode: 'static',
- reportFilename: "extension.html",
- openAnalyzer: false
- })
- ]
- },
- {
- name: 'panelWebView',
- target: 'web',
- entry: './src/panelWebView/index.tsx',
- output: {
- filename: 'panelWebView.js',
- path: path.resolve(__dirname, '../dist')
- },
- devtool: 'source-map',
- resolve: {
- extensions: ['.ts', '.js', '.tsx', '.jsx']
- },
- module: {
- rules: [
- {
- test: /\.(ts|tsx)$/,
- exclude: /node_modules/,
- use: [{
- loader: 'ts-loader'
- }]
- },
- {
- test: /\.css$/,
- use: ['style-loader', 'css-loader']
- },
- {
- test: /\.m?js/,
- resolve: {
- fullySpecified: false
- }
- }
- ]
- },
- performance: {
- maxEntrypointSize: 400000,
- maxAssetSize: 400000
- },
- // optimization: {
- // splitChunks: {
- // cacheGroups: {
- // vendors: {
- // test: /node_modules/,
- // chunks: 'initial',
- // filename: 'vendors.[contenthash].js',
- // priority: 1,
- // maxInitialRequests: 2, // create only one vendor file
- // minChunks: 1,
- // }
- // }
- // }
- // },
- plugins: [
- new BundleAnalyzerPlugin({
- analyzerMode: 'static',
- reportFilename: "viewpanel.html",
- openAnalyzer: false
- })
- ]
+ plugins: []
}
];
module.exports = (env, argv) => {
for (const configItem of config) {
configItem.mode = argv.mode;
+
+ if (argv.mode === 'production') {
+ configItem.plugins.push(new BundleAnalyzerPlugin({
+ analyzerMode: 'static',
+ reportFilename: "extension.html",
+ openAnalyzer: false
+ }));
+ }
}
return config;
diff --git a/webpack/panel.config.js b/webpack/panel.config.js
new file mode 100644
index 00000000..ae552b0e
--- /dev/null
+++ b/webpack/panel.config.js
@@ -0,0 +1,74 @@
+//@ts-check
+
+'use strict';
+
+const path = require('path');
+const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
+
+const config = [{
+ name: 'panel',
+ target: 'web',
+ entry: './src/panelWebView/index.tsx',
+ output: {
+ filename: 'panelWebView.js',
+ path: path.resolve(__dirname, '../dist')
+ },
+ devtool: 'source-map',
+ resolve: {
+ extensions: ['.ts', '.js', '.tsx', '.jsx'],
+ fallback: {
+ "path": require.resolve("path-browserify")
+ }
+ },
+ module: {
+ rules: [
+ {
+ test: /\.(ts|tsx)$/,
+ exclude: /node_modules/,
+ use: [{
+ loader: 'ts-loader'
+ }]
+ },
+ {
+ test: /\.css$/,
+ use: ['style-loader', 'css-loader']
+ },
+ {
+ test: /\.m?js/,
+ resolve: {
+ fullySpecified: false
+ }
+ }
+ ]
+ },
+ performance: {
+ maxEntrypointSize: 400000,
+ maxAssetSize: 400000
+ },
+ plugins: [],
+ devServer: {
+ compress: true,
+ port: 9001,
+ hot: true,
+ allowedHosts: "all",
+ headers: {
+ "Access-Control-Allow-Origin": "*",
+ }
+ }
+}];
+
+module.exports = (env, argv) => {
+ for (const configItem of config) {
+ configItem.mode = argv.mode;
+
+ if (argv.mode === 'production') {
+ configItem.plugins.push(new BundleAnalyzerPlugin({
+ analyzerMode: 'static',
+ reportFilename: "viewpanel.html",
+ openAnalyzer: false
+ }));
+ }
+ }
+
+ return config;
+};
\ No newline at end of file