Compare commits

...

217 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
bb9ea9f1b9 Support both content.config.* and src/content/config.* patterns for Astro content collections
Co-authored-by: estruyf <2900833+estruyf@users.noreply.github.com>
2025-06-13 12:47:05 +00:00
copilot-swe-agent[bot]
7d5fde1182 Initial plan for issue 2025-06-13 12:39:38 +00:00
Elio Struyf
9ce7754b1a Merge pull request #943 from stephanie-wertman/sw-welcome-text-typo
Improvements to Welcome screen
2025-04-16 11:25:12 +02:00
Stephanie Wertman
9f2f279c20 Rephrase welcome message in localization.enum.ts
Rephrase welcome message to join sentence fragments and improve tone.
2025-04-15 12:06:16 -07:00
Stephanie Wertman
0568149335 Rephrase welcome message in bundle.l10n.json
Rephrase welcome message to join sentence fragments and improve tone.
2025-04-15 12:04:02 -07:00
Elio Struyf
1b4e39b806 Merge pull request #924 from estruyf/beta
v10.8.0 release
2025-02-27 12:09:01 +01:00
Elio Struyf
1fa73efe11 Updated changelog 2025-02-27 11:59:28 +01:00
Elio Struyf
ddefb9f138 Copilot testing 2025-02-26 20:28:52 +01:00
Elio Struyf
5e258ac218 Feat: add file path support for slug generation and enhance slug template placeholders #922 2025-02-15 16:41:02 +01:00
Elio Struyf
d2b0228809 Feat: improve filename sanitization and add normalization for special characters #921 2025-02-14 09:35:12 +01:00
Elio Struyf
a164a849da Fix: add refresh button to media dashboard when custom scripts are defined 2025-02-12 15:01:13 +01:00
Elio Struyf
710ef136b4 Fix: improve media folder parsing on Windows and update path handling in various modules 2025-02-12 14:53:56 +01:00
Elio Struyf
d3b7f73c66 Refactor: update import paths for parseWinPath and integrate it into joinUrl function 2025-02-12 12:41:22 +01:00
Elio Struyf
ee5af88851 Fix: ensure Windows drive letters are lowercased and improve path parsing 2025-02-12 12:27:24 +01:00
Elio Struyf
482cbc3bf6 Issue: [[&mediaUrl]] placeholder in Media snippets is not relative #913 2025-02-06 11:40:22 +01:00
Elio Struyf
64f1da6355 Enhancement: auto switch to editor panel when opening a markdown file #915 2025-02-06 11:08:36 +01:00
Elio Struyf
e27adececb Issue: "panel.gitActions" option in view modes is not present in the JSON schema #909 2025-02-06 10:24:43 +01:00
Elio Struyf
b391aa3270 10.8.0 2025-02-06 10:20:39 +01:00
Elio Struyf
b58c02b6d0 Issue: Stripping underscore in default filename #914 2025-02-06 10:20:31 +01:00
Elio Struyf
88cad8caa2 Merge pull request #897 from estruyf/beta
v10.7.0 release
2024-12-31 15:28:43 +01:00
Elio Struyf
a04d56fbde 10.7.0 2024-12-31 15:24:47 +01:00
Elio Struyf
ec86b079a6 Update changelog 2024-12-31 15:23:28 +01:00
Elio Struyf
838ced0560 Remove logging 2024-12-30 11:40:12 +01:00
Elio Struyf
1c269db91d Issue: [BUG] Filtering on field with multiple values does not work as expected #895 2024-12-30 11:39:12 +01:00
Elio Struyf
1ed5131abe Change logging output 2024-12-29 13:18:30 +01:00
Elio Struyf
d944319d53 #896 - Fix glob node_modules ignore 2024-12-29 13:08:43 +01:00
Elio Struyf
146bbbf6a1 Added some verbose logging 2024-12-27 18:07:51 +01:00
Elio Struyf
7bfc72469d Merge pull request #893 from estruyf/issue/892
Add media folder actions and localization updates #892
2024-11-29 15:43:31 +01:00
Elio Struyf
324184964b Update media 2024-11-29 15:42:47 +01:00
Elio Struyf
1f6ea6ac20 Sorting on folders 2024-11-29 15:41:50 +01:00
Elio Struyf
5a45fdc94f Added progress 2024-11-29 15:19:22 +01:00
Elio Struyf
b043c22437 Add media folder actions and localization updates #892 2024-11-29 12:05:08 +01:00
Elio Struyf
b48e34ecb0 Remove CenterIcon ref 2024-11-28 18:24:54 +01:00
Elio Struyf
3bdae40ff0 Updated center layout icon 2024-11-28 18:19:42 +01:00
Elio Struyf
94df672f4c Updated yellow to warning 2024-11-28 18:18:55 +01:00
Elio Struyf
98c5b56310 Fix errors 2024-11-28 09:19:48 +01:00
Elio Struyf
f38144b8a7 Merge branch 'T3sT3ro-beta' into beta 2024-11-28 09:05:03 +01:00
Elio Struyf
231bd89619 Added density tooltip 2024-11-28 09:04:25 +01:00
Elio Struyf
4907a7aaa9 Merge branch 'beta' of github.com:T3sT3ro/vscode-front-matter into T3sT3ro-beta 2024-11-28 08:46:12 +01:00
Tooster
2dc4865581 #705 - fix styles - align checks badge padding and margin 2024-11-28 00:30:45 +01:00
Tooster
f1ae0d60cc #705 - UI tweaks and accessibility changes 2024-11-28 00:10:27 +01:00
Elio Struyf
2f76de2a28 #405 - Implement custom grouping option 2024-11-27 16:00:34 +01:00
Elio Struyf
d7282b18eb Update key 2024-11-27 15:58:57 +01:00
Elio Struyf
eb22a97198 Optimizations 2024-11-27 15:58:38 +01:00
Elio Struyf
42fe1c2887 #705 - Style changes 2024-11-25 16:49:47 +01:00
Elio Struyf
c02275d20b #705 - Style fixes 2024-11-25 13:41:43 +01:00
Elio Struyf
147823bfd0 #705 - update density 2024-11-25 12:00:07 +01:00
Elio Struyf
a7f183b6cc #705 - further improve keywords section 2024-11-25 11:59:22 +01:00
Elio Struyf
e10ee11f0e Fix title field on keywords section #705 2024-11-24 18:03:39 +01:00
Elio Struyf
fca8d260d5 Enhance SEO components with keyword management and styling updates #705 2024-11-22 09:27:46 +01:00
Elio Struyf
8cecf8d8be #705 - change order of metadata view 2024-11-21 16:40:24 +01:00
Elio Struyf
22ce41c3eb #705 - UX improvements for SEO panel 2024-11-21 16:14:25 +01:00
Elio Struyf
cb649a9a97 Add timezone formatting support and related settings #887 2024-11-14 16:30:46 +01:00
Elio Struyf
65d430b7cf Add GitHub Copilot prompt functionality #888 2024-11-13 10:24:24 +01:00
Elio Struyf
f1f0e0ab58 Merge pull request #886 from estruyf/beta
PR for v10.6.0
2024-11-06 11:06:01 +01:00
Elio Struyf
5f7f847ff8 Merge branch 'beta' of github.com:estruyf/vscode-front-matter into beta 2024-11-06 10:54:36 +01:00
Elio Struyf
2c4dbeb1eb update changelog 2024-11-06 10:54:32 +01:00
Elio Struyf
17164df11f Update fuse options 2024-11-04 19:37:00 +01:00
Elio Struyf
228c46084d Update categories 2024-11-04 18:39:47 +01:00
Elio Struyf
e838f18abc Remove unused ref 2024-11-04 13:42:36 +01:00
Elio Struyf
3d6359bc2e Issue: Content relationship field type is fetching forever #885 2024-11-04 13:20:18 +01:00
Elio Struyf
57b710cc61 Enhancement: hide WYSIWYG actions in git diff mode #884 2024-11-04 11:23:19 +01:00
Elio Struyf
7796d52ff9 Fix beta version 2024-10-28 16:25:49 +01:00
Elio Struyf
f8f539be0d #862 - evaluate the node command 2024-10-28 15:07:35 +01:00
Elio Struyf
fc96c8922c Feedback: Enum/Select in schema fields #859 2024-10-28 14:41:50 +01:00
Elio Struyf
c84af8493b Enhancement: dynamic evaluation of commands #882 2024-10-28 10:40:49 +01:00
Elio Struyf
6f288ff757 #879 Fix for auto updating last modified date on save 2024-10-24 14:25:34 +02:00
Elio Struyf
0e04e687fa #878 - Enhanced select all logic 2024-10-24 12:05:07 +02:00
Elio Struyf
cec3cbee3a Update changelog 2024-10-23 17:54:43 +02:00
Elio Struyf
c6f40194b4 Refactor snippet type display logic #867 2024-10-23 17:53:27 +02:00
Elio Struyf
6c591a90bd Merge pull request #877 from estruyf/beta
v10.5.1 changes
2024-10-23 17:37:17 +02:00
Elio Struyf
bece544934 Update changelog 2024-10-23 17:33:35 +02:00
Elio Struyf
c40fcba088 #872 - set default values in fields field type 2024-10-23 17:24:08 +02:00
Elio Struyf
ea9f8a2651 Remove debugger 2024-10-23 13:23:49 +02:00
Elio Struyf
b9b927c800 Retrieve correct default value #872 2024-10-23 13:23:31 +02:00
Elio Struyf
bc0f2e7bf7 Update changelog + version 2024-10-23 13:14:28 +02:00
Elio Struyf
b18f5e1e36 Removal of all punctuations from filename #875 2024-10-23 13:10:33 +02:00
Elio Struyf
8b05da5a76 Fix issue with default field value in field's 'when' clause #872 2024-10-23 12:29:12 +02:00
Elio Struyf
0062117c3b Fix media snippet markup insertion and clean up exclamation marks in file names #875 2024-10-23 12:17:01 +02:00
Elio Struyf
1d485adbca Fix media snippet markup insertion to article content's #874 2024-10-23 10:30:43 +02:00
Elio Struyf
9f2aa34aac 10.6.0 2024-10-23 09:44:36 +02:00
Elio Struyf
46a7a49e7c Optimize Copilot chat model retrieval #873 2024-10-23 09:44:29 +02:00
Elio Struyf
61ae29c37a Style changes 2024-10-23 09:28:03 +02:00
Elio Struyf
9d51531d59 Merge pull request #871 from estruyf/beta
Prep v10.5.0 release
2024-10-21 16:34:04 +02:00
Elio Struyf
0cb7d2463b Update workflows 2024-10-21 16:14:40 +02:00
Elio Struyf
ceeb1bf9a7 Updated changelog 2024-10-21 16:12:34 +02:00
Elio Struyf
c11efa56f1 #870 NumField component styles 2024-10-17 15:27:28 +02:00
Elio Struyf
fa3215fa64 Enhancement: Support Markdown in the WYSIWYG field #866 2024-10-10 09:21:09 +02:00
Elio Struyf
305c95fa86 Merge branch 'issue/865' into beta 2024-10-10 09:19:59 +02:00
Elio Struyf
3b7671afc9 Update schema 2024-10-10 09:19:47 +02:00
Elio Struyf
8660f5f680 Update type #840 2024-10-09 18:05:08 +02:00
Elio Struyf
2269994b43 separate the wysiwyg field 2024-10-09 14:13:55 +02:00
Elio Struyf
bdcd901e51 Merge branch 'beta' into issue/865 2024-10-09 10:07:38 +02:00
Elio Struyf
6d7df4266d #840 - Fix win path 2024-10-08 19:55:45 +02:00
Elio Struyf
8c2d243777 WIP 2024-10-08 19:40:58 +02:00
Elio Struyf
4282ec83e5 Add excludePaths option #840 2024-10-08 12:16:59 +02:00
Elio Struyf
0f3c43e0fc Fix button styling on the data screen #858 2024-10-08 09:31:40 +02:00
Elio Struyf
a377f27765 Update changelog 2024-10-07 22:00:12 +02:00
Elio Struyf
17860a18f4 Merge branch 'issue/851' of github.com:wottpal/vscode-front-matter into wottpal-issue/851 2024-10-07 21:58:08 +02:00
Elio Struyf
73609ca346 Update changelog 2024-10-07 21:32:47 +02:00
Elio Struyf
d6dfa8c9cf Merge branch 'wottpal-issue/850' into beta 2024-10-07 21:18:40 +02:00
Elio Struyf
1c00362b1c Updated localization 2024-10-07 21:17:56 +02:00
Elio Struyf
63ea564734 #863 fix empty page folder cache 2024-10-07 21:14:58 +02:00
Elio Struyf
38f128e1b6 Merge branch 'issue/850' of github.com:wottpal/vscode-front-matter into wottpal-issue/850 2024-10-07 20:59:59 +02:00
Dennis Zoma
39704f3a55 feat: Add option to filter content relationship options by active locale 2024-10-07 10:54:20 +02:00
Dennis Zoma
2020198e90 fix: Fix issue of filtering incorrect content types 2024-10-07 09:13:42 +02:00
Dennis Zoma
ba1cf95ffd feat: Show slug in content relationship combobox option 2024-10-07 08:38:22 +02:00
Dennis Zoma
aea87a6168 feat: Add action to create or open translation file dynamically 2024-10-07 08:04:29 +02:00
Elio Struyf
179a71db39 Merge pull request #861 from davidsneighbour/patch-1
fix: typo
2024-10-05 10:00:35 +02:00
Patrick Kollitsch
8d8e3fe3cc fix: typo 2024-10-02 13:15:27 +07:00
Elio Struyf
3d8c550f60 10.5.0 2024-09-27 11:14:43 +02:00
Elio Struyf
6fd526e962 Added eslint to webpack config 2024-09-27 11:14:34 +02:00
Elio Struyf
788d0241fd Merge pull request #856 from estruyf/beta
10.4.1
2024-09-27 09:04:04 +02:00
Elio Struyf
017a2d7597 #855 - Fix collapsible state 2024-09-27 09:03:30 +02:00
Elio Struyf
3019ba1dff 10.4.1 2024-09-27 08:44:11 +02:00
Elio Struyf
13e58d26a1 Merge pull request #854 from estruyf/beta
Release 10.4.0
2024-09-25 08:49:50 +02:00
Elio Struyf
634196b056 Update release date 2024-09-25 08:21:52 +02:00
Elio Struyf
8b95468c78 datetime type fields not respecting empty default value #853 2024-09-23 10:02:48 +02:00
Elio Struyf
dc23aba128 Updated lib 2024-09-20 09:12:21 +02:00
Elio Struyf
a778be9737 Add manifest 2024-09-19 15:08:49 +02:00
Elio Struyf
b9508df4f8 webpack update + loading prod files 2024-09-19 12:57:39 +02:00
Elio Struyf
0110b7365c #844 - Exclude hidden files and verify if valid 2024-09-19 08:48:00 +02:00
Elio Struyf
6588b90e7d Added collapsible panes 2024-09-18 14:05:12 +02:00
Elio Struyf
47dba5f510 #841 - Remove dash on folder notation 2024-09-18 09:20:54 +02:00
Elio Struyf
121a84659f Show non-empty fields in metadata panel #849 2024-09-18 09:18:58 +02:00
Elio Struyf
620966c08e Update vscrui version 2024-09-16 17:50:29 +02:00
Elio Struyf
06718c3577 #837 - Update panels component 2024-09-16 17:31:22 +02:00
Elio Struyf
178207fd82 #837 - Update dropdowns 2024-09-16 16:06:39 +02:00
Elio Struyf
657e9054f6 Added release notes link 2024-09-16 14:34:24 +02:00
Elio Struyf
36a8002cea Merge branch 'beta' of github.com:estruyf/vscode-front-matter into beta 2024-09-16 12:13:39 +02:00
Elio Struyf
07f124dcf5 Add empty view heading for creating new data file #834 2024-09-16 12:13:30 +02:00
Elio Struyf
ff1d4487f4 #848 - change the default GH Copilot model + optimized prompts 2024-09-13 21:59:57 +02:00
Elio Struyf
66151083c0 #844 - new {{filePrefix.index}} placeholder 2024-09-13 14:08:20 +02:00
Elio Struyf
83abff67ac #837 - Adopt vscrui components 2024-09-13 13:43:34 +02:00
Elio Struyf
431a83b882 #841 - enable placeholders in file prefixes 2024-09-09 14:42:35 +02:00
Elio Struyf
d240e8fdc8 #846 - Add GH Copilot action for title field 2024-09-09 12:35:24 +02:00
Elio Struyf
e95e9a8fc7 #842 - Allow the slug to be set to an empty value 2024-09-06 14:12:12 +02:00
Elio Struyf
d8e3338abe Include hidden files 2024-09-05 15:35:50 +02:00
Elio Struyf
6f6b97e6ca Update beta script 2024-09-05 14:23:55 +02:00
Elio Struyf
3f8665cadf #845 - Fix empty values for number fields 2024-09-05 14:05:37 +02:00
Elio Struyf
8cc68be4da Merge branch 'main' into beta 2024-08-15 19:53:50 +02:00
Elio Struyf
27f2b57c24 #833 - Fix localization key/values 2024-08-15 19:52:44 +02:00
Elio Struyf
9b1be1a6c1 feat: Add support for Asciidoc files #833 2024-08-14 16:26:29 +02:00
Elio Struyf
d0b7af5c86 Enhancement: Ability to create new data files for a folder #834 2024-08-14 14:06:52 +02:00
Elio Struyf
f13058c59b Prep changelog 2024-08-14 11:01:35 +02:00
Elio Struyf
cf28e5fc85 10.4.0 2024-08-14 11:00:47 +02:00
Elio Struyf
cf787ab0f6 Merge branch 'beta' 2024-08-14 10:56:55 +02:00
Elio Struyf
c7424a6d73 Update sponsor image 2024-08-14 10:56:19 +02:00
Elio Struyf
2d607bdb5b Merge pull request #839 from estruyf/beta
PR for 10.3.0 release
2024-08-13 17:44:42 +02:00
Elio Struyf
823d99aff2 Fix pkg file 2024-08-13 17:42:00 +02:00
Elio Struyf
9005a94355 Merge branches 'beta' and 'main' of github.com:estruyf/vscode-front-matter into beta 2024-08-13 17:38:32 +02:00
Elio Struyf
dff2fb0149 Update date of 10.3.0 release 2024-08-13 17:33:05 +02:00
Elio Struyf
7d3653589b Update changelog 2024-08-13 13:39:32 +02:00
Elio Struyf
31460026ee Hide media scripts when empty 2024-08-13 09:21:32 +02:00
Elio Struyf
1a97a11c1c 10.2.1 2024-08-08 14:18:38 +02:00
Elio Struyf
430760eca8 #820 - Update API URLs 2024-08-08 14:18:27 +02:00
Elio Struyf
800acde914 Update dev branch 2024-08-08 12:25:47 +02:00
Elio Struyf
06ff07bec8 JSON schema update 2024-08-07 14:22:52 +02:00
Elio Struyf
27a4d9bc71 #820 - Update API URL 2024-08-07 14:22:43 +02:00
Elio Struyf
45f2794631 #823 - added support for v1.92.0 2024-08-05 10:38:46 +02:00
Elio Struyf
42f6557bd6 Update beta logo 2024-07-24 15:29:26 +02:00
Elio Struyf
78d42ac09b Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2024-07-24 14:16:01 +02:00
Elio Struyf
73e00a7a94 #820 - Update endpoints 2024-07-24 14:15:50 +02:00
Elio Struyf
36e0ef0171 Substring update 2024-07-21 20:41:10 +02:00
Elio Struyf
380bc804fd Update beta script 2024-07-21 20:37:43 +02:00
Elio Struyf
458aadcbef Add os and vscode info to diagnostic logging 2024-07-21 20:15:28 +02:00
Elio Struyf
adb541805a Update node modules ignore 2024-07-21 15:25:08 +02:00
Elio Struyf
e7ca5488de Fix for finding folders with wildcards in the path #832 2024-07-21 15:21:39 +02:00
Elio Struyf
f583e0e91a #820 - Update endpoints 2024-07-19 16:29:10 +02:00
Elio Struyf
00bbb3879f Telemetry removal 2024-07-18 17:08:16 +02:00
Elio Struyf
1d7436d051 chore: Update website and API hosts #820 2024-07-18 16:47:22 +02:00
Elio Struyf
86de4fa767 feat: Add select all action #831 2024-07-18 16:35:17 +02:00
Elio Struyf
ced7e41fe6 feat: Add support for DefaultFields.Keywords in ContentTypeValidator #467 2024-07-09 21:26:52 +02:00
Elio Struyf
b81e92ef9e Fix for fieldCollection 2024-07-09 21:10:05 +02:00
Elio Struyf
ec3c1eec58 feat: Add URI handler for command links from documentation #821 2024-07-09 17:15:20 +02:00
Elio Struyf
c173fe973c feat: Add support for fmContentType metadata field #467. 2024-07-09 13:31:19 +02:00
Elio Struyf
47e8caeede Issue: slug placeholder not working if there is no title field #830 2024-07-03 14:35:25 +02:00
Elio Struyf
5b3223abb6 Enhancement: Allow UI extensibility out of experimental mode #829 2024-07-03 11:59:12 +02:00
Elio Struyf
2cb6c89d87 Fix localization 2024-07-01 10:36:34 +02:00
Elio Struyf
4197de2b2e #824 - Added support in single image field 2024-06-28 17:42:19 +02:00
Elio Struyf
fe7a296cc1 Style fix 2024-06-28 13:22:55 +02:00
Elio Struyf
b03d972d31 #824 - Field actions 2024-06-28 09:23:26 +02:00
Elio Struyf
0e6e776f70 #827 - Fix team settings file recreation 2024-06-27 21:35:20 +02:00
Elio Struyf
bd1fc32f1c #823 - Copilot setting 2024-06-27 14:39:22 +02:00
Elio Struyf
38d48b9fa7 Update changelog 2024-06-26 11:37:54 +02:00
Elio Struyf
c92a5cac00 Merge branch 'copilot-integration' into dev 2024-06-26 11:36:26 +02:00
Elio Struyf
3a4e9fd8ff #823 - Support titles and taxonomy 2024-06-26 11:35:02 +02:00
Elio Struyf
e77de75333 Updated dependencies 2024-06-26 09:27:43 +02:00
Elio Struyf
b00d7a077d #823 - First steps into integrating GH Copilot 2024-06-25 22:25:16 +02:00
Elio Struyf
582c09875e Add docs #822 2024-06-20 11:39:26 +02:00
Elio Struyf
0c9b4a31ac Added doc links for vscode 2024-06-17 09:28:56 +02:00
Elio Struyf
e8fc53804c Update 2024-06-17 09:15:05 +02:00
Elio Struyf
5b7486a355 Update readme 2024-06-16 12:14:35 +02:00
Elio Struyf
d23e0833dc Update readme 2024-06-16 12:14:12 +02:00
Elio Struyf
dacc6214b6 Updated readme 2024-06-16 12:13:38 +02:00
Elio Struyf
314cadb81e Merge branch 'hotfix/10.2.1' into dev 2024-06-14 13:40:42 +02:00
Elio Struyf
1e1c0cedb0 #812 - Support for case 2 2024-06-14 13:40:02 +02:00
Elio Struyf
013324b3f0 Merge branch 'main' into hotfix/10.2.1 2024-06-14 12:14:14 +02:00
Elio Struyf
62056753e4 10.3.0 2024-06-13 16:35:24 +02:00
Elio Struyf
6b018c0b65 #819 - Added new extensibility support for media scripts 2024-06-13 16:35:10 +02:00
Elio Struyf
ef9510d92d Merge pull request #818 from mayumih387/dev
Added new translations (Japanese)
2024-06-13 14:30:31 +02:00
mayumih387
6d4cd4b0c2 Revised translations 2024-06-13 12:37:53 +09:00
mayumih387
e529f30a40 Added translations for new lines 2024-06-13 12:33:08 +09:00
mayumihara
8b92a3306f Merge branch 'estruyf:dev' into dev 2024-06-13 11:35:52 +09:00
Elio Struyf
5353d07fcb Merge pull request #817 from estruyf/dev
Merge for release 10.2.0
2024-06-12 12:16:23 +02:00
Elio Struyf
1f94ae165c Update changelog 2024-06-12 12:12:52 +02:00
Elio Struyf
dbd42ac1f9 Merge branch 'dev' of github.com:estruyf/vscode-front-matter into dev 2024-06-12 11:52:38 +02:00
Elio Struyf
1031088f85 Added disable stable ext on debug 2024-06-12 11:52:26 +02:00
Elio Struyf
fcbbe7f834 Updated changelog 2024-06-10 15:18:26 +02:00
Elio Struyf
c58d0573c6 #811 - Update default feature flags 2024-06-10 15:07:07 +02:00
Elio Struyf
ba7a0225c1 Update changelog 2024-06-10 11:48:48 +02:00
Elio Struyf
65fd8b4a78 #806 - Small fixes 2024-06-10 11:32:20 +02:00
Elio Struyf
46af17eac2 Update logging 2024-06-07 10:05:11 +02:00
Elio Struyf
2eb0b775a3 Extra logging 2024-06-07 09:52:44 +02:00
Elio Struyf
bf07f29698 Extra logging 2024-06-07 09:42:06 +02:00
mayumih387
5882853f28 Added new descriptions 2024-06-03 14:32:05 +09:00
Elio Struyf
a571b34724 Merge pull request #795 from estruyf/dev
v10.1.0 release
2024-04-11 17:20:16 +02:00
259 changed files with 11580 additions and 3297 deletions

View File

@@ -12,6 +12,9 @@
"no-throw-literal": "error",
"no-unused-expressions": "error",
"curly": "error",
"class-methods-use-this": "warn"
"class-methods-use-this": "warn",
"no-console": "warn",
"@typescript-eslint/no-empty-interface": "off",
"no-extra-boolean-cast": "off"
}
}

View File

@@ -20,7 +20,7 @@ runs:
steps:
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
registry-url: https://registry.npmjs.org/
cache: 'npm'
@@ -42,5 +42,6 @@ runs:
- uses: actions/upload-artifact@v4
with:
include-hidden-files: true
name: ${{ inputs.PACKAGE_NAME }}
path: .

View File

@@ -2,7 +2,7 @@ name: BETA Release
on:
push:
branches:
- dev
- beta
workflow_dispatch:
env:
@@ -41,7 +41,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
registry-url: https://registry.npmjs.org/
cache: 'npm'
@@ -69,7 +69,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
registry-url: https://registry.npmjs.org/
cache: 'npm'

View File

@@ -41,7 +41,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
registry-url: https://registry.npmjs.org/
cache: 'npm'
@@ -69,7 +69,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 20
registry-url: https://registry.npmjs.org/
cache: 'npm'

8
.vscode/launch.json vendored
View File

@@ -10,7 +10,9 @@
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"args": [
"--extensionDevelopmentPath=${workspaceFolder}", "--disable-extension=eliostruyf.vscode-front-matter"
],
"outFiles": ["${workspaceFolder}/dist/**/*.js"],
"preLaunchTask": "npm: build:ext"
},
@@ -19,7 +21,9 @@
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"args": [
"--extensionDevelopmentPath=${workspaceFolder}", "--disable-extension=eliostruyf.vscode-front-matter"
],
"outFiles": ["${workspaceFolder}/dist/**/*.js"]
}
]

16
.vscode/settings.json vendored
View File

@@ -1,11 +1,15 @@
// Place your settings in this file to overwrite default and user settings.
{
"workbench.colorCustomizations": {
"titleBar.activeBackground": "#15c2cb",
"titleBar.inactiveBackground": "#44ffd299",
"titleBar.activeForeground": "#0E131F",
"titleBar.inactiveForeground": "#0E131F99"
},
"commitHelper.messages": [
{
"type": "👨‍💻 apps",
"values": ["#search", "#profile"]
},
{
"type": "⚙️ tasks",
"values": ["#build", "#deploy", "#skip"]
}
],
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},

View File

@@ -1,6 +1,134 @@
# Change Log
## [10.2.0] - 2024-xx-xx
## [10.8.0] - 2025-02-27 - [Release notes](https://beta.frontmatter.codes/updates/v10.8.0)
### 🎨 Enhancements
- [#915](https://github.com/estruyf/vscode-front-matter/issues/915): Added a new setting `frontMatter.panel.openOnSupportedFile` which allows you to open the panel view on supported files
- [#921](https://github.com/estruyf/vscode-front-matter/issues/921): Improve the filename sanitization
- [#922](https://github.com/estruyf/vscode-front-matter/issues/922): Added `{{fileName}}` and `{{sluggedFileName}}` placeholders for the slug template setting
### 🐞 Fixes
- Fix for media folder parsing on Windows
- Refresh button was not available on the media dashboard when having custom scripts defined
- [#909](https://github.com/estruyf/vscode-front-matter/issues/909): Schema fix for the view modes
- [#913](https://github.com/estruyf/vscode-front-matter/issues/913): Fix for relative media paths in page bundles
- [#914](https://github.com/estruyf/vscode-front-matter/issues/914): Fix sanitizing of default filenames with an `_` in it
## [10.7.0] - 2024-12-31 - [Release notes](https://beta.frontmatter.codes/updates/v10.7.0)
### 🎨 Enhancements
- [#405](https://github.com/estruyf/vscode-front-matter/issues/405): Added new `frontMatter.content.grouping` setting which allows you to define custom "group by" options
- [#705](https://github.com/estruyf/vscode-front-matter/issues/705): UX improvements for the panel view
- [#887](https://github.com/estruyf/vscode-front-matter/issues/887): Added new `frontMatter.global.timezone` setting, by default it is set to `UTC` for date formatting
- [#888](https://github.com/estruyf/vscode-front-matter/issues/888): Added the ability to prompt GitHub Copilot from a custom script/action
- [#892](https://github.com/estruyf/vscode-front-matter/issues/892): Added media folder common actions
### 🐞 Fixes
- [#895](https://github.com/estruyf/vscode-front-matter/issues/895): Fix issue with array values in filters
## [10.6.0] - 2024-11-06 - [Release notes](https://beta.frontmatter.codes/updates/v10.6.0)
### 🎨 Enhancements
- [#878](https://github.com/estruyf/vscode-front-matter/issues/878): Allow the `select all` button to work on other pages when there is a selection present
- [#882](https://github.com/estruyf/vscode-front-matter/issues/882): Dynamic evaluation of the `node` executable path
- [#884](https://github.com/estruyf/vscode-front-matter/issues/884): Hide WYSIWYG actions when the file is in git diff mode
### 🐞 Fixes
- [#859](https://github.com/estruyf/vscode-front-matter/issues/859): Fix label in the data view dropdown field
- [#876](https://github.com/estruyf/vscode-front-matter/issues/876): Fix snippet type on the snippet card
- [#879](https://github.com/estruyf/vscode-front-matter/issues/879): Fix for auto updating last modified date on save
- [#885](https://github.com/estruyf/vscode-front-matter/issues/885): Fix content relationship for none i18n content
## [10.5.1] - 2024-10-23
### 🎨 Enhancements
- [#873](https://github.com/estruyf/vscode-front-matter/issues/873): Add retry logic to get the AI model for calling GitHub Copilot
### 🐞 Fixes
- [#872](https://github.com/estruyf/vscode-front-matter/issues/872): Check the default field value as well for the field's `when` clause
- [#874](https://github.com/estruyf/vscode-front-matter/issues/874): Fix media snippet markup insertion to article content's
- [#875](https://github.com/estruyf/vscode-front-matter/issues/875): Clean up the exclamation marks from the file name when creating new content
## [10.5.0] - 2024-10-21 - [Release notes](https://beta.frontmatter.codes/updates/v10.5.0)
### 🎨 Enhancements
- [#840](https://github.com/estruyf/vscode-front-matter/issues/840): Added the `excludePaths` option for the content folder settings
- [#850](https://github.com/estruyf/vscode-front-matter/issues/850): Extended the i18n/language button to open or create new language files (thanks to [Dennis Zoma](https://github.com/wottpal))
- [#851](https://github.com/estruyf/vscode-front-matter/issues/851): Added `sameContentLocale` option to `contentRelationship` field (thanks to [Dennis Zoma](https://github.com/wottpal))
- [#866](https://github.com/estruyf/vscode-front-matter/issues/866): Support Markdown in the WYSIWYG `string` field
### 🐞 Fixes
- [#858](https://github.com/estruyf/vscode-front-matter/issues/858): Fix button styling on the data screen
- [#860](https://github.com/estruyf/vscode-front-matter/issues/860): Fix typo on the data screen
- [#870](https://github.com/estruyf/vscode-front-matter/issues/870): Fix data number field styling
## [10.4.1] - 2024-09-27
- [#855](https://github.com/estruyf/vscode-front-matter/issues/855): Fix in panel sections
## [10.4.0] - 2024-09-25 - [Release notes](https://beta.frontmatter.codes/updates/v10.4.0)
### ✨ New features
- [#844](https://github.com/estruyf/vscode-front-matter/issues/844): New `{{filePrefix.index}}` placeholder to add the index number of the file in the folder
### 🎨 Enhancements
- [#833](https://github.com/estruyf/vscode-front-matter/issues/833): Added support for Asciidoc files
- [#834](https://github.com/estruyf/vscode-front-matter/issues/834): Added the ability to create new data files for a data folder
- [#841](https://github.com/estruyf/vscode-front-matter/issues/841): Enable placeholders for file prefixes
- [#846](https://github.com/estruyf/vscode-front-matter/issues/846): Added GitHub Copilot action for title field
- [#848](https://github.com/estruyf/vscode-front-matter/issues/848): Set the default GitHub Copilot model to `gpt-4o-mini`
### 🐞 Fixes
- [#842](https://github.com/estruyf/vscode-front-matter/issues/842): Allow to set the `frontMatter.taxonomy.slugTemplate` setting to an empty string
- [#845](https://github.com/estruyf/vscode-front-matter/issues/845): Fix empty values for number fields
- [#849](https://github.com/estruyf/vscode-front-matter/issues/849): Show fields which are not empty in the metadata panel
- [#853](https://github.com/estruyf/vscode-front-matter/issues/853): Allow empty values in date fields
### 🚧 Work in progress
- [#837](https://github.com/estruyf/vscode-front-matter/issues/837): Replacing the VSCode Webview UI Toolkit with [vscrui](https://github.com/estruyf/vscrui) due to the deprecation of the VSCode Webview UI Toolkit library
## [10.3.0] - 2024-08-13 - [Release notes](https://beta.frontmatter.codes/updates/v10.3.0)
### ✨ New features
- [#823](https://github.com/estruyf/vscode-front-matter/issues/823): Integrated GitHub Copilot support for titles, descriptions, and taxonomy field suggestions
- [#824](https://github.com/estruyf/vscode-front-matter/issues/824): Added the ability to link custom actions to fields
### 🎨 Enhancements
- [#467](https://github.com/estruyf/vscode-front-matter/issues/467): New `fmContentType` metadata field to link content type (fallback to the `type` field)
- [#819](https://github.com/estruyf/vscode-front-matter/issues/819): Added new extensibility support for media scripts
- [#820](https://github.com/estruyf/vscode-front-matter/issues/820): Moving the website and API to different hosts
- [#821](https://github.com/estruyf/vscode-front-matter/issues/821): Added URI handler to support command links from the documentation
- [#822](https://github.com/estruyf/vscode-front-matter/issues/822): Added docs to the panel & dashboard views
- [#829](https://github.com/estruyf/vscode-front-matter/issues/829): UI extensibility is now generally available
- [#831](https://github.com/estruyf/vscode-front-matter/issues/831): Added "select all" action bar button to the content and media dashboards
### 🐞 Fixes
- [#827](https://github.com/estruyf/vscode-front-matter/issues/827): Fix for `frontmatter.json` file which gets created when already present in a sub-folder
- [#830](https://github.com/estruyf/vscode-front-matter/issues/830): Fix for using the SEO title field setting to change the title field reference
- [#832](https://github.com/estruyf/vscode-front-matter/issues/832): Fix for finding folders with wildcards in the path
## [10.2.1] - 2024-08-08
- [#820](https://github.com/estruyf/vscode-front-matter/issues/820): Update API links to the new API URL
## [10.2.0] - 2024-06-12 - [Release notes](https://beta.frontmatter.codes/updates/v10.2.0)
### ✨ New features
@@ -9,15 +137,15 @@
### 🎨 Enhancements
- [#441](https://github.com/estruyf/vscode-front-matter/issues/441): Show input descriptions for snippet and data forms
- [#442](https://github.com/estruyf/vscode-front-matter/issues/442): Hide sidebar on data view when data file is selecte + show dropdown of data files
- [#442](https://github.com/estruyf/vscode-front-matter/issues/442): Hide sidebar on data view when data file is selected + show dropdown of data files
- [#788](https://github.com/estruyf/vscode-front-matter/issues/788): Show a warning on setting update when it exists in an extended configuration
- [#798](https://github.com/estruyf/vscode-front-matter/issues/798): Changed dialog to slide-over for the snippet forms
- [#799](https://github.com/estruyf/vscode-front-matter/issues/799): Added `frontMatter.logging` setting to define the logging output. Options are `info`, `warn`, `error`, and `verbose`. Default is `info`.
- [#799](https://github.com/estruyf/vscode-front-matter/issues/799): Added `frontMatter.logging` setting to define the logging output. Options are `info`, `warn`, `error`, and `verbose`. The default is `info`.
- [#800](https://github.com/estruyf/vscode-front-matter/issues/800): Add colors for the Front Matter CMS output
- [#808](https://github.com/estruyf/vscode-front-matter/issues/808): Add support to generate field groups and `block` fields in content type generation
- [#810](https://github.com/estruyf/vscode-front-matter/issues/810): Update the tab title based on the view
- [#811](https://github.com/estruyf/vscode-front-matter/issues/811): Added `panel.gitActions` view mode option to hide the Git actions in the panel
- [#812](https://github.com/estruyf/vscode-front-matter/issues/812): Added the `{{locale}}` placeholder which can be used in the `previewPath` property
- [#812](https://github.com/estruyf/vscode-front-matter/issues/812): Added the `{{locale}}` placeholder, which can be used in the `previewPath` property
### ⚡️ Optimizations

View File

@@ -179,25 +179,17 @@ You can open showcase issues for the following things:
</a>
</p>
## 🖤 Backers & Sponsors 👇 🤘
## 💚 Backers & Sponsors 👇 🤘
<p align="center">
<img src="https://frontmatter.codes/api/img-sponsors" alt="Front Matter sponsors" />
<img src="https://api.frontmatter.codes/img-sponsors" alt="Front Matter sponsors" />
</p>
<br />
<p align="center" title="Powered by Vercel">
<a href="https://run.events/?utm_source=frontmatter&utm_campaign=oss">
<img src="https://frontmatter.codes/assets/sponsors/runevents-purple.webp" alt="run.events - Event Management Platform" height="50px" />
</a>
</p>
<br />
<p align="center" title="Powered by Vercel">
<a href="https://vercel.com/?utm_source=vscode-frontmatter&utm_campaign=oss">
<img src="https://frontmatter.codes/assets/sponsors/powered-by-vercel.png" alt="Powered by Vercel" height="44px" />
<p align="center" title="Powered by Netlify">
<a href="https://www.netlify.com?utm_source=vscode-frontmatter&utm_campaign=oss">
<img src="https://frontmatter.codes/assets/sponsors/netlify-dark.png" alt="Deploys by Netlify" height="51px" />
</a>
</p>
@@ -211,18 +203,7 @@ You can open showcase issues for the following things:
## 📊 Telemetry
The Front Matter CMS extension collects telemetry data to help us build a better understand which features from the CMS are used. The extension respects the `telemetry.enableTelemetry` setting which you can learn more about in the [Visual Studio Code FAQ](https://aka.ms/vscode-remote/telemetry), or you can only disable it for the extension by configuring the `frontMatter.telemetry.disable` setting.
We only collect the following data:
- Type of event
- Extension title (main or beta)
- Extension version
No user-specific data is collected, you can check the telemetry implementation in the following files:
- [Telemetry class](https://github.com/estruyf/vscode-front-matter/blob/59528a3db01be8d34dc40638e6cf827090e31986/src/helpers/Telemetry.ts)
- [Metrics API](https://github.com/FrontMatter/web-documentation-nextjs/blob/main/pages/api/metrics.ts)
The Front Matter CMS extension only uses telemetry on application crashes. The extension respects the `telemetry.enableTelemetry` setting which you can learn more about in the [Visual Studio Code FAQ](https://aka.ms/vscode-remote/telemetry).
For crash reports in the webviews, we make use of Sentry to help us understand what went wrong. This data is only used to fix issues and improve the extension. You can find more information about the Sentry implementation in the following files:

View File

@@ -177,15 +177,15 @@ You can open showcase issues for the following things:
</a>
</p>
## 🖤 Backers & Sponsors 👇 🤘
## 💚 Backers & Sponsors 👇 🤘
<p align="center">
<img src="https://frontmatter.codes/api/img-sponsors" alt="Front Matter sponsors" />
<img src="https://api.frontmatter.codes/img-sponsors" alt="Front Matter sponsors" />
</p>
<br />
<p align="center" title="Powered by Vercel">
<p align="center" title="Support by run.events">
<a href="https://run.events/?utm_source=frontmatter&utm_campaign=oss">
<img src="https://frontmatter.codes/assets/sponsors/runevents-purple.webp" alt="run.events - Event Management Platform" height="50px" />
</a>
@@ -193,9 +193,9 @@ You can open showcase issues for the following things:
<br />
<p align="center" title="Powered by Vercel">
<a href="https://vercel.com/?utm_source=vscode-frontmatter&utm_campaign=oss">
<img src="https://frontmatter.codes/assets/sponsors/powered-by-vercel.png" alt="Powered by Vercel" height="44px" />
<p align="center" title="Powered by Netlify">
<a href="https://www.netlify.com?utm_source=vscode-frontmatter&utm_campaign=oss">
<img src="https://frontmatter.codes/assets/sponsors/netlify-dark.png" alt="Deploys by Netlify" height="51px" />
</a>
</p>
@@ -209,18 +209,7 @@ You can open showcase issues for the following things:
## 📊 Telemetry
The Front Matter CMS extension collects telemetry data to help us build a better understand which features from the CMS are used. The extension respects the `telemetry.enableTelemetry` setting which you can learn more about in the [Visual Studio Code FAQ](https://aka.ms/vscode-remote/telemetry), or you can only disable it for the extension by configuring the `frontMatter.telemetry.disable` setting.
We only collect the following data:
- Type of event
- Extension title (main or beta)
- Extension version
No user-specific data is collected, you can check the telemetry implementation in the following files:
- [Telemetry class](https://github.com/estruyf/vscode-front-matter/blob/59528a3db01be8d34dc40638e6cf827090e31986/src/helpers/Telemetry.ts)
- [Metrics API](https://github.com/FrontMatter/web-documentation-nextjs/blob/main/pages/api/metrics.ts)
The Front Matter CMS extension only uses telemetry on application crashes. The extension respects the `telemetry.enableTelemetry` setting which you can learn more about in the [Visual Studio Code FAQ](https://aka.ms/vscode-remote/telemetry).
For crash reports in the webviews, we make use of Sentry to help us understand what went wrong. This data is only used to fix issues and improve the extension. You can find more information about the Sentry implementation in the following files:

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -1,45 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 25.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 28 28" style="enable-background:new 0 0 28 28;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFE45E;}
.st1{fill:none;stroke:#FFE45E;stroke-width:2;stroke-miterlimit:10;}
.st2{font-family:'MyriadPro-Bold';}
.st3{font-size:8px;}
</style>
<g>
<g>
<path class="st0" d="M4.1,10.2H2.4V2.1h3.1V4H4.1v1.2h1.2V7H4.1V10.2z"/>
<path class="st0" d="M10.7,10.2H8.9L8,7.3c0-0.1,0-0.1,0-0.2C7.9,7.1,7.9,7,7.8,6.8v0.6v2.9H6.1V2.1h1.8c0.8,0,1.3,0.2,1.8,0.6
c0.5,0.5,0.8,1.2,0.8,2.1c0,1-0.4,1.6-1.1,2L10.7,10.2z M7.9,5.8L7.9,5.8c0.3,0,0.5-0.1,0.6-0.3S8.7,5,8.7,4.8c0-0.6-0.3-1-0.8-1
l0,0V5.8z"/>
<path class="st0" d="M16.1,6.2c0,1.2-0.2,2.3-0.7,3.1s-1.1,1.2-1.7,1.2s-1.2-0.3-1.6-0.9c-0.6-0.8-0.9-1.9-0.9-3.4
s0.3-2.6,0.9-3.4C12.6,2.3,13,2,13.7,2c0.8,0,1.3,0.4,1.8,1.2C15.8,3.8,16.1,4.8,16.1,6.2z M14.3,6.2c0-1.4-0.2-2.2-0.7-2.2
c-0.2,0-0.4,0.2-0.5,0.6c-0.1,0.4-0.2,0.9-0.2,1.6c0,0.7,0.1,1.2,0.2,1.6c0.1,0.4,0.3,0.6,0.5,0.6c0.2,0,0.4-0.2,0.5-0.6
C14.2,7.3,14.3,6.9,14.3,6.2z"/>
<path class="st0" d="M16.8,10.2V2.1h1.7l0.9,2.9c0.1,0.1,0.1,0.3,0.2,0.6c0.1,0.2,0.1,0.5,0.2,0.8L20,7c-0.1-0.7-0.1-1.3-0.2-1.8
s-0.1-1-0.1-1.2V2.1h1.7v8.2h-1.6l-0.9-3c-0.1-0.3-0.2-0.6-0.3-0.9c-0.1-0.3-0.1-0.6-0.2-0.8c0,0.6,0.1,1.1,0.1,1.5
c0,0.4,0,0.8,0,1.2v2.1h-1.7V10.2z"/>
<path class="st0" d="M24.6,10.2h-1.7V4h-1V2.1h3.7V4h-1.1V10.2z"/>
</g>
</g>
<rect class="st1" width="28" height="28"/>
<g>
<g>
<path class="st0" d="M3.1,11.6H4l0.6,3c0.1,0.4,0.2,0.8,0.2,1.2C4.9,16.2,4.9,16.6,5,17c0-0.1,0-0.1,0-0.1v-0.1l0.2-0.9l0.1-0.8
l0.1-0.5l0.6-3h0.9l0.7,7.5h-1l-0.2-2.6c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.2v-1v-0.9l0,0c0,0,0,0,0-0.1v0.2c0,0.2,0,0.3-0.1,0.5
c-0.1,0.2,0,0.2-0.1,0.3L6,15.7V16l-0.6,3.3H4.7l-0.6-2.8c-0.1-0.4-0.2-0.8-0.2-1.1c-0.1-0.4-0.1-0.8-0.2-1.2l-0.3,5.2h-1
L3.1,11.6z"/>
<path class="st0" d="M9.4,11.6h0.8l1.6,7.5h-1l-0.3-1.5H9l-0.3,1.5h-1L9.4,11.6z M10.4,16.8l-0.3-1.2C10,14.8,9.8,13.9,9.7,13
c0,0.5-0.1,0.9-0.2,1.4c-0.1,0.5-0.2,1-0.3,1.5l-0.2,1L10.4,16.8L10.4,16.8z"/>
<path class="st0" d="M11.6,11.6h3.3v0.9h-1.1v6.7h-1v-6.7h-1.2V11.6z"/>
<path class="st0" d="M14.9,11.6h3.3v0.9h-1.1v6.7h-1v-6.7h-1.2V11.6z"/>
<path class="st0" d="M18.8,11.6h2.7v0.9h-1.7v2.4h1.5v0.9h-1.5v2.6h1.7v0.9h-2.7V11.6z"/>
<path class="st0" d="M22.3,11.6h1.3c0.6,0,1,0.1,1.2,0.4c0.3,0.3,0.5,0.9,0.5,1.6c0,0.5-0.1,1-0.3,1.3c-0.2,0.3-0.4,0.5-0.8,0.6
l1.4,3.7h-1l-1.4-3.7v3.7h-1L22.3,11.6L22.3,11.6z M23.3,14.9c0.4,0,0.7-0.1,0.8-0.3c0.2-0.2,0.2-0.5,0.2-0.9c0-0.2,0-0.4-0.1-0.6
c-0.1-0.2-0.1-0.3-0.2-0.4c-0.1-0.1-0.2-0.2-0.3-0.2s-0.3-0.1-0.4-0.1h-0.2v2.5H23.3z"/>
</g>
</g>
<text transform="matrix(1 0 0 1 5.4457 25.9479)" class="st0 st2 st3">BETA</text>
</svg>
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 28 28">
<defs>
<style>
.cls-1 {
stroke-width: 0px;
}
.cls-1, .cls-2, .cls-3, .cls-4 {
fill: #c91980;
}
.cls-2 {
font-family: Futura-MediumItalic, Futura;
font-size: 8px;
font-style: italic;
}
.cls-2, .cls-3, .cls-4, .cls-5 {
isolation: isolate;
}
.cls-2, .cls-4 {
font-weight: 500;
}
.cls-3 {
font-family: Futura-CondensedExtraBold, Futura;
font-size: 10.6px;
font-weight: 700;
}
.cls-4 {
font-family: Futura-CondensedMedium, Futura;
font-size: 10.1px;
}
</style>
</defs>
<g class="cls-5">
<text class="cls-4" transform="translate(2.1 18.9) scale(1 1)"><tspan x="0" y="0">MATTER</tspan></text>
</g>
<g class="cls-5">
<text class="cls-2" transform="translate(1.9 26)"><tspan x="0" y="0">BETA</tspan></text>
</g>
<rect class="cls-1" x="2.4" width="3" height="1"/>
<rect class="cls-1" x="6.9" width="3" height="1"/>
<rect class="cls-1" x="11.4" width="3" height="1"/>
<rect class="cls-1" x="2.4" y="27" width="3" height="1"/>
<rect class="cls-1" x="6.9" y="27" width="3" height="1"/>
<rect class="cls-1" x="11.4" y="27" width="3" height="1"/>
<g class="cls-5">
<text class="cls-3" transform="translate(2.1 10.1) scale(.8 1)"><tspan x="0" y="0">FRONT</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -75,7 +75,7 @@
}
.frontmatter h3 {
margin-bottom: 1rem;
/* margin-bottom: 1rem; */
}
.frontmatter p,
@@ -99,11 +99,6 @@
margin-right: 0.5rem;
}
.seo__status__details,
.seo__status__keywords {
margin-bottom: 1rem;
}
.collapsible__body h4 {
text-align: center;
font-weight: bold;
@@ -131,7 +126,8 @@
}
.article__tags__dropbox.open {
border: 1px solid rgba(0, 0, 0, 0.9);
border: 1px solid var(--vscode-focusBorder);
width: 100%;
}
.article__tags ul {
@@ -224,6 +220,7 @@
text-decoration: none;
width: 100%;
white-space: nowrap;
border-radius: 0.25rem;
}
.ext_link_block button.active {

View File

@@ -258,9 +258,6 @@
"panel.fields.textField.limit": "Feldgrenze erreicht {0}",
"panel.fields.wrapperField.unknown": "Unbekannter Feldtyp: {0}",
"panel.actions.title": "Aktionen",
"panel.articleDetails.title": "Weitere Details",
"panel.articleDetails.type": "Typ",
"panel.articleDetails.total": "Gesamt",
"panel.articleDetails.headings": "Überschriften",
"panel.articleDetails.paragraphs": "Absätze",
"panel.articleDetails.internalLinks": "Interne Links",
@@ -299,16 +296,13 @@
"panel.publishAction.publish": "Veröffentlichen",
"panel.publishAction.unpublish": "Zurück zu Entwurf",
"panel.seoDetails.recommended": "Empfohlen",
"panel.seoKeywordInfo.density": "Stichwortdichte {0} *",
"panel.seoKeywordInfo.validInfo.label": "Verwendet in Überschrift(en)",
"panel.seoKeywordInfo.validInfo.content": "Inhalt",
"panel.seoKeywords.title": "Stichwörter",
"panel.seoKeywords.header.keyword": "Stichwort",
"panel.seoKeywords.header.details": "Details",
"panel.seoKeywords.density": "* Eine Stichwortdichte von 1-1,5 % ist in den meisten Fällen ausreichend.",
"panel.seoStatus.title": "Empfehlungen",
"panel.seoKeywords.density.description": "* Eine Stichwortdichte von 1-1,5 % ist in den meisten Fällen ausreichend.",
"panel.seoStatus.header.property": "Eigenschaft",
"panel.seoStatus.header.length": "Länge",
"panel.seoStatus.header.valid": "Gültig",
"panel.seoStatus.seoFieldInfo.characters": "{0} Zeichen",
"panel.seoStatus.seoFieldInfo.words": "{0} Wörter",

View File

@@ -263,9 +263,6 @@
"panel.fields.textField.limit": "Limite de champ atteinte {0}",
"panel.fields.wrapperField.unknown": "Type de champ inconnu : {0}",
"panel.actions.title": "Actions",
"panel.articleDetails.title": "Plus de détails",
"panel.articleDetails.type": "Type",
"panel.articleDetails.total": "Total",
"panel.articleDetails.headings": "En-têtes",
"panel.articleDetails.paragraphs": "Paragraphes",
"panel.articleDetails.internalLinks": "Liens internes",
@@ -304,16 +301,13 @@
"panel.publishAction.publish": "Publié",
"panel.publishAction.unpublish": "Retourner au brouillon",
"panel.seoDetails.recommended": "Recommandé",
"panel.seoKeywordInfo.density": "Utilisation du mot clé {0} *",
"panel.seoKeywordInfo.validInfo.label": "Utilisé dans le ou les en-tête(s)",
"panel.seoKeywordInfo.validInfo.content": "Contenu",
"panel.seoKeywords.title": "Mot-clés",
"panel.seoKeywords.header.keyword": "Mot-clé",
"panel.seoKeywords.header.details": "Détails",
"panel.seoKeywords.density": "* Une densité de mot-clé de 1-1.5% est suffisante dans la plupart des cas",
"panel.seoStatus.title": "Recommandations",
"panel.seoKeywords.density.description": "* Une densité de mot-clé de 1-1.5% est suffisante dans la plupart des cas",
"panel.seoStatus.header.property": "Propriété",
"panel.seoStatus.header.length": "Longueur",
"panel.seoStatus.header.valid": "Valide",
"panel.seoStatus.seoFieldInfo.characters": "{0} caractères",
"panel.seoStatus.seoFieldInfo.words": "{0} mots",

View File

@@ -263,9 +263,6 @@
"panel.fields.textField.limit": "Limite di campi raggiunto {0}",
"panel.fields.wrapperField.unknown": "Tipo di campo sconosciuto: {0}",
"panel.actions.title": "Azioni",
"panel.articleDetails.title": "Più dettagli",
"panel.articleDetails.type": "Digitare",
"panel.articleDetails.total": "Totale",
"panel.articleDetails.headings": "Intestazioni",
"panel.articleDetails.paragraphs": "Paragrafi",
"panel.articleDetails.internalLinks": "Collegamenti esterni",
@@ -304,16 +301,13 @@
"panel.publishAction.publish": "Pubblica",
"panel.publishAction.unpublish": "Tornare alla bozza",
"panel.seoDetails.recommended": "Raccomandato",
"panel.seoKeywordInfo.density": "Utilizzo delle parole chiave {0} *",
"panel.seoKeywordInfo.validInfo.label": "Utilizzato nelle rubriche",
"panel.seoKeywordInfo.validInfo.content": "Contenuto",
"panel.seoKeywords.title": "Parole chiavi",
"panel.seoKeywords.header.keyword": "Parola chiave",
"panel.seoKeywords.header.details": "Dettagli",
"panel.seoKeywords.density": "* Una densità di parole chiave dell'1-1,5% è sufficiente nella maggior parte dei casi.",
"panel.seoStatus.title": "Consigli",
"panel.seoKeywords.density.description": "* Una densità di parole chiave dell'1-1,5% è sufficiente nella maggior parte dei casi.",
"panel.seoStatus.header.property": "Proprietà",
"panel.seoStatus.header.length": "Lunghezza",
"panel.seoStatus.header.valid": "Valido",
"panel.seoStatus.seoFieldInfo.characters": "{0} caratteri",
"panel.seoStatus.seoFieldInfo.words": "{0} parole",

View File

@@ -274,6 +274,8 @@
"dashboard.preview.button.refresh.title": "更新",
"dashboard.preview.button.open.title": "開く",
"dashboard.snippetsView.item.type.content": "コンテンツ用スニペット",
"dashboard.snippetsView.item.type.media": "メディア用スニペット",
"dashboard.snippetsView.item.quickAction.editSnippet": "スニペットを編集",
"dashboard.snippetsView.item.quickAction.deleteSnippet": "スニペットを削除",
"dashboard.snippetsView.item.quickAction.viewSnippet": "スニペットファイルの表示",
@@ -436,9 +438,6 @@
"panel.actions.title": "コマンド",
"panel.articleDetails.title": "詳細",
"panel.articleDetails.type": "項目",
"panel.articleDetails.total": "数",
"panel.articleDetails.headings": "見出し",
"panel.articleDetails.paragraphs": "パラグラフ",
"panel.articleDetails.internalLinks": "内部リンク",
@@ -487,18 +486,15 @@
"panel.seoDetails.recommended": "推奨",
"panel.seoKeywordInfo.density": "キーワード出現率 {0} *",
"panel.seoKeywordInfo.validInfo.label": "見出しへの利用",
"panel.seoKeywordInfo.validInfo.content": "本文",
"panel.seoKeywords.title": "キーワード",
"panel.seoKeywords.header.keyword": "キーワード",
"panel.seoKeywords.header.details": "詳細",
"panel.seoKeywords.density": "* キーワード出現率は通常1~1.5%で十分です。",
"panel.seoKeywords.density.description": "* キーワード出現率は通常1~1.5%で十分です。",
"panel.seoStatus.title": "推奨項目",
"panel.seoStatus.header.property": "項目",
"panel.seoStatus.header.length": "長さ",
"panel.seoStatus.header.valid": "有効",
"panel.seoStatus.seoFieldInfo.characters": "{0} 文字",
"panel.seoStatus.seoFieldInfo.words": "{0} 語",
@@ -725,6 +721,7 @@
"helpers.settingsHelper.readConfig.progress.title": "{0}: 動的な設定ファイルを読み込んでいます...",
"helpers.settingsHelper.readConfig.error": "設定の読み込みでエラーが発生しました。",
"helpers.settingsHelper.refreshConfig.success": "設定を再読み込みしました。",
"helpers.settingsHelper.safeUpdate.warning": "Front Matter CMSの構成が拡張または分割されているため、\"{0}\"の設定を更新できませんでした。手動で更新を加えてください。更新情報についての出力を確認してください。",
"helpers.taxonomyHelper.rename.input.title": "タクソノミー名を変更 {0}",
"helpers.taxonomyHelper.rename.validate.equalValue": "現在のファイル名とは別のファイル名を入力してください。",

View File

@@ -43,6 +43,7 @@
"common.languages": "Languages",
"common.scripts": "Scripts",
"common.rename": "Rename",
"common.docs": "Documentation",
"loading.initPages": "Loading content",
@@ -55,6 +56,8 @@
"settings.view.integration": "Integration",
"settings.openOnStartup": "Open dashboard on startup",
"settings.openPanelForSupportedFiles": "Open panel for supported files",
"settings.openPanelForSupportedFiles.label": "Do you want to open the panel for supported files?",
"settings.contentTypes": "Content types",
"settings.contentFolders": "Content folders",
"settings.diagnostic": "Diagnostic",
@@ -139,8 +142,12 @@
"dashboard.dataView.dataView.noDataFiles": "No data files found",
"dashboard.dataView.dataView.getStarted.link": "Read more to get started using data files",
"dashboard.dataView.dataView.update.message": "Updated your data entries",
"dashboard.dataView.dataView.createNew": "Create new data file",
"dashboard.dataView.dataView.selectDataFolder": "Select data folder",
"dashboard.dataView.dataView.closeSelectedDataFile": "Close data file",
"dashboard.dataView.emptyView.heading": "Select your date type first",
"dashboard.dataView.emptyView.heading": "Select your data type first",
"dashboard.dataView.emptyView.heading.create": "Start by creating a new data file",
"dashboard.dataView.sortableItem.editButton.title": "Edit \"{0}\"",
"dashboard.dataView.sortableItem.deleteButton.title": "Delete \"{0}\"",
@@ -153,6 +160,7 @@
"dashboard.filters.languageFilter.all": "All",
"dashboard.header.actionsBar.itemsSelected": "{0} selected",
"dashboard.header.actionsBar.selectAll": "Select all",
"dashboard.header.actionsBar.alertDelete.title": "Delete selected files",
"dashboard.header.actionsBar.alertDelete.description": "Are you sure you want to delete the selected files?",
@@ -181,7 +189,7 @@
"dashboard.header.pagination.first": "First",
"dashboard.header.pagination.previous": "Previous",
"dashboard.header.pagination.next": "next",
"dashboard.header.pagination.next": "Next",
"dashboard.header.pagination.last": "Last",
"dashboard.header.paginationStatus.text": "Showing {0} to {1} of {2} results",
@@ -241,6 +249,7 @@
"dashboard.media.folderItem.contentDirectory": "Content directory",
"dashboard.media.folderItem.publicDirectory": "Public directory",
"dashboard.media.folderItem.deleteDescription": "Are you sure you want to delete the folder ({0})?",
"dashboard.media.item.buttom.insert.image": "Insert image",
"dashboard.media.item.buttom.insert.snippet": "Insert snippet",
@@ -362,7 +371,7 @@
"dashboard.welcomeScreen.title": "Manage your static site with Front Matter",
"dashboard.welcomeScreen.thanks": "Thank you for using Front Matter!",
"dashboard.welcomeScreen.description": "We try to aim to make Front Matter as easy to use as possible, but if you have any questions or suggestions. Please don't hesitate to reach out to us on GitHub.",
"dashboard.welcomeScreen.description": "We aim to make Front Matter as easy to use as possible. If you have any questions or suggestions, please contact us on GitHub.",
"dashboard.welcomeScreen.link.github.title": "GitHub",
"dashboard.welcomeScreen.link.github.label": "GitHub",
"dashboard.welcomeScreen.link.documentation.label": "Documentation",
@@ -430,17 +439,18 @@
"panel.fields.slugField.generate": "Generate slug",
"panel.fields.textField.ai.message": "Use Front Matter AI to suggest {0}",
"panel.fields.textField.copilot.message": "Use Copilot to suggest {0}",
"panel.fields.textField.ai.generate": "Generating suggestion...",
"panel.fields.textField.loading": "Loading field",
"panel.fields.textField.limit": "Field limit reached {0}",
"panel.fields.wrapperField.unknown": "Unkown field type: {0}",
"panel.fields.fieldCustomAction.button.title": "Custom action",
"panel.fields.fieldCustomAction.executing": "Executing field action...",
"panel.actions.title": "Actions",
"panel.articleDetails.title": "More details",
"panel.articleDetails.type": "Type",
"panel.articleDetails.total": "Total",
"panel.articleDetails.headings": "Headings",
"panel.articleDetails.paragraphs": "Paragraphs",
"panel.articleDetails.internalLinks": "Internal links",
@@ -489,18 +499,20 @@
"panel.seoDetails.recommended": "Recommended",
"panel.seoKeywordInfo.density": "Keyword usage {0} *",
"panel.seoKeywordInfo.validInfo.label": "Used in heading(s)",
"panel.seoKeywords.checks": "Checks",
"panel.seoKeywords.density.tableTitle": "Frequency",
"panel.seoKeywords.density": "Keyword density",
"panel.seoKeywordInfo.validInfo.label": "Heading(s)",
"panel.seoKeywordInfo.validInfo.content": "Content",
"panel.seoKeywordInfo.density.tooltip": "Recommended frequency: 0.75% - 1.5%",
"panel.seoKeywords.title": "Keywords",
"panel.seoKeywords.header.keyword": "Keyword",
"panel.seoKeywords.header.details": "Details",
"panel.seoKeywords.density": "* A keyword density of 1-1.5% is sufficient in most cases.",
"panel.seoKeywords.density.description": "* A keyword density of 1-1.5% is sufficient in most cases.",
"panel.seoStatus.title": "Recommendations",
"panel.seoStatus.title": "Insights",
"panel.seoStatus.header.property": "Property",
"panel.seoStatus.header.length": "Length",
"panel.seoStatus.header.valid": "Valid",
"panel.seoStatus.seoFieldInfo.characters": "{0} chars",
"panel.seoStatus.seoFieldInfo.words": "{0} words",
@@ -520,6 +532,7 @@
"panel.tagPicker.inputPlaceholder.empty": "Pick your {0}",
"panel.tagPicker.inputPlaceholder.disabled": "You have reached the limit of {0}",
"panel.tagPicker.ai.suggest": "Use Front Matter AI to suggest {0}",
"panel.tagPicker.copilot.suggest": "Use GitHub Copilot to suggest {0}",
"panel.tagPicker.ai.generating": "Generating suggestions...",
"panel.tagPicker.limit": "Max.: {0}",
"panel.tagPicker.unkown": "Add the unknown tag",
@@ -572,6 +585,11 @@
"commands.i18n.create.success.created": "Created \"{0}\" i18n content file.",
"commands.i18n.create.quickPick.title": "Create content for locale",
"commands.i18n.create.quickPick.placeHolder": "To which locale do you want to create a new content?",
"commands.i18n.createOrOpen.quickPick.title": "Open or create translation",
"commands.i18n.createOrOpen.quickPick.category.existing": "Existing translations",
"commands.i18n.createOrOpen.quickPick.action.open": "Open \"{0}\"",
"commands.i18n.createOrOpen.quickPick.category.new": "New translations",
"commands.i18n.createOrOpen.quickPick.action.create": "Create \"{0}\"",
"commands.i18n.translate.progress.title": "Translating content...",
"commands.preview.panel.title": "Preview: {0}",
@@ -703,9 +721,11 @@
"helpers.questions.contentTitle.aiInput.placeholder": "What would you like to write about?",
"helpers.questions.contentTitle.aiInput.quickPick.title.separator": "your title/description",
"helpers.questions.contentTitle.aiInput.quickPick.ai.separator": "AI generated title",
"helpers.questions.contentTitle.aiInput.quickPick.copilot.separator": "GitHub Copilot suggestions",
"helpers.questions.contentTitle.aiInput.select.title": "Select a title",
"helpers.questions.contentTitle.aiInput.select.placeholder": "Select a title for your content",
"helpers.questions.contentTitle.aiInput.failed": "Failed fetching the AI title. Please try to use your own title or try again later.",
"helpers.questions.contentTitle.copilotInput.failed": "Failed fetching the GitHub Copilot title suggestions. Please try to use your own title or try again later.",
"helpers.questions.contentTitle.aiInput.warning": "You did not specify a title for your content.",
"helpers.questions.contentTitle.titleInput.title": "Content title",
"helpers.questions.contentTitle.titleInput.prompt": "What would you like to use as a title for the content to create?",
@@ -758,6 +778,9 @@
"listeners.dashboard.dashboardListener.pinItem.coundNotPin.error": "Could not pin item.",
"listeners.dashboard.dashboardListener.pinItem.coundNotUnPin.error": "Could not unpin item.",
"listeners.dashboard.mediaListeners.deleteMediaFolder.progress.title": "Deleting folder...",
"listeners.dashboard.mediaListeners.updateMediaFolder.progress.title": "Updating folder...",
"listeners.dashboard.settingsListener.triggerTemplate.notification": "Template files copied.",
"listeners.dashboard.settingsListener.triggerTemplate.progress.title": "Downloading and initializing the template...",
"listeners.dashboard.settingsListener.triggerTemplate.download.error": "Failed to download the template.",
@@ -774,11 +797,15 @@
"listeners.panel.dataListener.aiSuggestTaxonomy.noData.error": "No article data",
"listeners.panel.dataListener.getDataFileEntries.noDataFiles.error": "Couldn't find data file entries",
"listeners.panel.dataListener.pushMetadata.frontMatter.error": "Something went wrong while parsing your front matter. Please check the contents of your file.",
"listeners.panel.dataListener.createDataFile.inputTitle": "What is the name of the data file?",
"listeners.panel.dataListener.createDataFile.error": "No data file id or path defined.",
"listeners.panel.dataListener.createDataFile.noFileName": "No filename provided.",
"listeners.panel.taxonomyListener.aiSuggestTaxonomy.noEditor.error": "No active editor",
"listeners.panel.taxonomyListener.aiSuggestTaxonomy.noData.error": "No article data",
"services.copilot.getChatResponse.error": "Failed to get a response from the GitHub Copilot.",
"services.modeSwitch.switchMode.quickPick.placeholder": "Select the mode you want to use",
"services.modeSwitch.switchMode.quickPick.title": "{0}: Mode selection",
"services.modeSwitch.setText.mode": "Mode: {0}",
@@ -791,4 +818,4 @@
"services.sponsorAi.getTaxonomySuggestions.warning": "The AI taxonomy generation took too long. Please try again later.",
"services.terminal.openLocalServerTerminal.terminalOption.message": "Starting local server"
}
}

6314
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,14 +3,15 @@
"displayName": "Front Matter CMS",
"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, Docusaurus, NextJs, Gatsby, and many more...",
"icon": "assets/frontmatter-teal-128x128.png",
"version": "10.2.0",
"version": "10.8.0",
"preview": false,
"publisher": "eliostruyf",
"galleryBanner": {
"color": "#0e131f",
"theme": "dark"
},
"badges": [{
"badges": [
{
"description": "version",
"url": "https://img.shields.io/github/package-json/v/estruyf/vscode-front-matter?color=green&label=vscode-front-matter&style=flat-square",
"href": "https://github.com/estruyf/vscode-front-matter"
@@ -26,11 +27,12 @@
},
"qna": "https://github.com/estruyf/vscode-front-matter/discussions",
"engines": {
"vscode": "^1.73.0"
"vscode": "^1.90.0"
},
"l10n": "./l10n",
"categories": [
"Other"
"AI",
"Visualization"
],
"keywords": [
"Front Matter",
@@ -69,7 +71,8 @@
"**/.frontmatter/config/*.json": "jsonc"
}
},
"keybindings": [{
"keybindings": [
{
"command": "frontMatter.dashboard",
"key": "alt+d"
},
@@ -93,19 +96,23 @@
}
],
"viewsContainers": {
"activitybar": [{
"id": "frontmatter-explorer",
"title": "FM",
"icon": "$(fm-logo)"
}]
"activitybar": [
{
"id": "frontmatter-explorer",
"title": "FM",
"icon": "$(fm-logo)"
}
]
},
"views": {
"frontmatter-explorer": [{
"id": "frontMatter.explorer",
"name": "Front Matter",
"icon": "$(fm-logo)",
"type": "webview"
}]
"frontmatter-explorer": [
{
"id": "frontMatter.explorer",
"name": "Front Matter",
"icon": "$(fm-logo)",
"type": "webview"
}
]
},
"configuration": {
"title": "%settings.configuration.title%",
@@ -173,7 +180,8 @@
"frontMatter.content.defaultFileType": {
"type": "string",
"default": "md",
"oneOf": [{
"oneOf": [
{
"enum": [
"md",
"mdx"
@@ -189,7 +197,8 @@
"frontMatter.content.defaultSorting": {
"type": "string",
"default": "",
"oneOf": [{
"oneOf": [
{
"enum": [
"LastModifiedAsc",
"LastModifiedDesc",
@@ -282,6 +291,14 @@
"default": false,
"description": "%setting.frontMatter.content.pageFolders.items.properties.excludeSubdir.description%"
},
"excludePaths": {
"type": "array",
"default": false,
"description": "%setting.frontMatter.content.pageFolders.items.properties.excludePaths.description%",
"items": {
"type": "string"
}
},
"previewPath": {
"type": [
"null",
@@ -467,6 +484,34 @@
"additionalProperties": false
}
},
"frontMatter.content.grouping": {
"type": "array",
"default": [],
"markdownDescription": "%setting.frontMatter.content.grouping.markdownDescription%",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "%setting.frontMatter.content.grouping.items.properties.id.description%"
},
"title": {
"type": "string",
"description": "%setting.frontMatter.content.grouping.items.properties.title.description%"
},
"name": {
"type": "string",
"description": "%setting.frontMatter.content.grouping.items.properties.name.description%"
}
},
"additionalProperties": false,
"required": [
"title",
"name"
]
},
"scope": "Content"
},
"frontMatter.content.sorting": {
"type": "array",
"default": [],
@@ -541,7 +586,8 @@
"categories"
],
"markdownDescription": "%setting.frontMatter.content.filters.markdownDescription%",
"items": [{
"items": [
{
"type": "string",
"enum": [
"contentFolders",
@@ -567,6 +613,7 @@
"default": [],
"markdownDescription": "%setting.frontMatter.custom.scripts.markdownDescription%",
"items": {
"$id": "#customscript",
"type": "object",
"properties": {
"id": {
@@ -614,7 +661,8 @@
"command": {
"$id": "#scriptCommand",
"type": "string",
"anyOf": [{
"anyOf": [
{
"enum": [
"node",
"bash",
@@ -810,7 +858,8 @@
"title",
"file"
],
"anyOf": [{
"anyOf": [
{
"required": [
"schema"
]
@@ -857,6 +906,20 @@
"type": "boolean",
"description": "%setting.frontMatter.data.folders.items.properties.singleEntry.description%",
"default": false
},
"enableFileCreation": {
"type": "boolean",
"description": "%setting.frontMatter.data.folders.items.properties.enableFileCreation.description%",
"default": false
},
"fileType": {
"type": "string",
"default": "json",
"enum": [
"json",
"yaml"
],
"description": "%setting.frontMatter.data.folders.items.properties.fileType.description%"
}
},
"additionalProperties": false,
@@ -864,7 +927,8 @@
"id",
"path"
],
"anyOf": [{
"anyOf": [
{
"required": [
"schema"
]
@@ -997,8 +1061,9 @@
"panel.globalSettings",
"panel.seo",
"panel.actions",
"panel.contentType",
"panel.metadata",
"panel.contentType",
"panel.gitActions",
"panel.recentlyModified",
"panel.otherActions",
"dashboard.snippets.view",
@@ -1032,7 +1097,7 @@
"error"
],
"markdownDescription": "%setting.frontMatter.global.notifications.markdownDescription%",
"scope": "Templates"
"scope": "Global"
},
"frontMatter.global.disabledNotifications": {
"type": "array",
@@ -1042,6 +1107,12 @@
"requiredFieldValidation"
]
},
"frontMatter.global.timezone": {
"default": "UTC",
"type": "string",
"markdownDescription": "%setting.frontMatter.global.timezone.markdownDescription%",
"scope": "Global"
},
"frontMatter.media.defaultSorting": {
"type": "string",
"default": "",
@@ -1105,26 +1176,29 @@
}
}
},
"default": [{
"name": "default",
"fileTypes": null,
"fields": [{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Caption",
"name": "caption",
"type": "string"
},
{
"title": "Alt text",
"name": "alt",
"type": "string"
}
]
}],
"default": [
{
"name": "default",
"fileTypes": null,
"fields": [
{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Caption",
"name": "caption",
"type": "string"
},
{
"title": "Alt text",
"name": "alt",
"type": "string"
}
]
}
],
"scope": "Media"
},
"frontMatter.media.supportedMimeTypes": {
@@ -1140,6 +1214,12 @@
},
"scope": "Media"
},
"frontMatter.panel.openOnSupportedFile": {
"type": "boolean",
"default": false,
"markdownDescription": "%setting.frontMatter.panel.openOnSupportedFile.markdownDescription%",
"scope": "Dashboard"
},
"frontMatter.panel.freeform": {
"type": "boolean",
"default": true,
@@ -1176,7 +1256,7 @@
"scope": "Site preview"
},
"frontMatter.preview.trailingSlash": {
"type": "string",
"type": "boolean",
"default": "",
"markdownDescription": "%setting.frontMatter.preview.trailingSlash.markdownDescription%",
"scope": "Site preview"
@@ -1227,9 +1307,16 @@
"fileType": {
"type": "string",
"default": "",
"enum": [
"md",
"mdx"
"oneOf": [
{
"enum": [
"md",
"mdx"
]
},
{
"type": "string"
}
],
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fileType.description%"
},
@@ -1336,7 +1423,14 @@
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.single.description%"
},
"wysiwyg": {
"type": "boolean",
"type": [
"boolean",
"string"
],
"enum": [
"html",
"markdown"
],
"default": false,
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.wysiwyg.description%"
},
@@ -1360,7 +1454,8 @@
"default": "",
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.taxonomyId.description%",
"not": {
"anyOf": [{
"anyOf": [
{
"const": ""
},
{
@@ -1504,6 +1599,11 @@
"default": "path",
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeValue.description%"
},
"sameContentLocale": {
"type": "boolean",
"default": true,
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.sameContentLocale.description%"
},
"when": {
"type": "object",
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.description%",
@@ -1547,6 +1647,13 @@
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.caseSensitive.description%"
}
}
},
"actions": {
"type": "array",
"description": "%setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.actions.description%",
"items": {
"$ref": "#customscript"
}
}
},
"additionalProperties": false,
@@ -1554,7 +1661,8 @@
"type",
"name"
],
"allOf": [{
"allOf": [
{
"if": {
"properties": {
"type": {
@@ -1766,48 +1874,51 @@
"fields"
]
},
"default": [{
"name": "default",
"pageBundle": false,
"fields": [{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Description",
"name": "description",
"type": "string"
},
{
"title": "Publishing date",
"name": "date",
"type": "datetime",
"default": "{{now}}",
"isPublishDate": true
},
{
"title": "Content preview",
"name": "preview",
"type": "image"
},
{
"title": "Is in draft",
"name": "draft",
"type": "boolean"
},
{
"title": "Tags",
"name": "tags",
"type": "tags"
},
{
"title": "Categories",
"name": "categories",
"type": "categories"
}
]
}],
"default": [
{
"name": "default",
"pageBundle": false,
"fields": [
{
"title": "Title",
"name": "title",
"type": "string"
},
{
"title": "Description",
"name": "description",
"type": "string"
},
{
"title": "Publishing date",
"name": "date",
"type": "datetime",
"default": "{{now}}",
"isPublishDate": true
},
{
"title": "Content preview",
"name": "preview",
"type": "image"
},
{
"title": "Is in draft",
"name": "draft",
"type": "boolean"
},
{
"title": "Tags",
"name": "tags",
"type": "tags"
},
{
"title": "Categories",
"name": "categories",
"type": "categories"
}
]
}
],
"scope": "Taxonomy"
},
"frontMatter.taxonomy.customTaxonomy": {
@@ -1820,7 +1931,8 @@
"type": "string",
"description": "%setting.frontMatter.taxonomy.customTaxonomy.items.properties.id.description%",
"not": {
"anyOf": [{
"anyOf": [
{
"const": ""
},
{
@@ -1964,7 +2076,11 @@
"scope": "Taxonomy"
},
"frontMatter.taxonomy.slugTemplate": {
"type": "string",
"type": [
"string",
"null"
],
"default": null,
"markdownDescription": "%setting.frontMatter.taxonomy.slugTemplate.markdownDescription%",
"scope": "Taxonomy"
},
@@ -1976,11 +2092,6 @@
},
"scope": "Taxonomy"
},
"frontMatter.telemetry.disable": {
"type": "boolean",
"default": false,
"markdownDescription": "%setting.frontMatter.telemetry.disable.markdownDescription%"
},
"frontMatter.templates.enabled": {
"type": "boolean",
"default": false,
@@ -1995,7 +2106,7 @@
},
"frontMatter.templates.prefix": {
"type": "string",
"default": "yyyy-MM-dd",
"default": "{{date|yyyy-MM-dd}}",
"markdownDescription": "%setting.frontMatter.templates.prefix.markdownDescription%",
"scope": "Templates"
},
@@ -2012,10 +2123,16 @@
"info",
"verbose"
]
},
"frontMatter.copilot.family": {
"type": "string",
"default": "gpt-4o-mini",
"markdownDescription": "%setting.frontMatter.copilot.family.markdownDescription%"
}
}
},
"commands": [{
"commands": [
{
"command": "frontMatter.project.switch",
"title": "%command.frontMatter.project.switch%",
"category": "Front Matter",
@@ -2268,6 +2385,12 @@
"title": "%command.frontMatter.preview%",
"category": "Front Matter"
},
{
"command": "frontMatter.docs",
"title": "%command.frontMatter.docs%",
"category": "Front Matter",
"icon": "$(book)"
},
{
"command": "frontMatter.chatbot",
"title": "%command.frontMatter.chatbot%",
@@ -2331,6 +2454,15 @@
"title": "%command.frontMatter.cache.clear%",
"category": "Front Matter"
},
{
"command": "frontMatter.i18n.createOrOpen",
"title": "%command.frontMatter.i18n.createOrOpen%",
"category": "Front Matter",
"icon": {
"light": "assets/icons/i18n-light.svg",
"dark": "assets/icons/i18n-dark.svg"
}
},
{
"command": "frontMatter.i18n.create",
"title": "%command.frontMatter.i18n.create%",
@@ -2341,84 +2473,89 @@
}
}
],
"submenus": [{
"id": "frontmatter.submenu",
"label": "Front Matter"
}],
"submenus": [
{
"id": "frontmatter.submenu",
"label": "Front Matter"
}
],
"menus": {
"webview/context": [{
"command": "workbench.action.webview.openDeveloperTools",
"when": "frontMatter:isDevelopment"
}],
"editor/title": [{
"webview/context": [
{
"command": "workbench.action.webview.openDeveloperTools",
"when": "frontMatter:isDevelopment"
}
],
"editor/title": [
{
"command": "frontMatter.markup.heading",
"group": "navigation@-133",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.bold",
"group": "navigation@-132",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.italic",
"group": "navigation@-131",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.hyperlink",
"group": "navigation@-130",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.insertSnippet",
"group": "navigation@-129",
"when": "frontMatter:file:isValid == true && frontMatter:dashboard:snippets:enabled"
"when": "frontMatter:file:isValid == true && frontMatter:dashboard:snippets:enabled && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.insertMedia",
"group": "navigation@-128",
"when": "frontMatter:file:isValid == true"
"when": "frontMatter:file:isValid == true && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.i18n.create",
"command": "frontMatter.i18n.createOrOpen",
"group": "navigation@-127",
"when": "frontMatter:file:isValid && frontMatter:i18n:enabled"
},
{
"command": "frontMatter.markup.options",
"group": "navigation@-126",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.orderedlist",
"group": "1_markup@1",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.unorderedlist",
"group": "1_markup@2",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.tasklist",
"group": "1_markup@3",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.code",
"group": "1_markup@4",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.codeblock",
"group": "1_markup@5",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.markup.blockquote",
"group": "1_markup@6",
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg"
"when": "frontMatter:file:isValid == true && frontMatter:markdown:wysiwyg && activeEditor == 'workbench.editors.files.textFileEditor'"
},
{
"command": "frontMatter.dashboard",
@@ -2436,11 +2573,14 @@
"when": "resourceFilename == 'frontmatter.json'"
}
],
"explorer/context": [{
"submenu": "frontmatter.submenu",
"group": "frontmatter@1"
}],
"frontmatter.submenu": [{
"explorer/context": [
{
"submenu": "frontmatter.submenu",
"group": "frontmatter@1"
}
],
"frontmatter.submenu": [
{
"command": "frontMatter.createFromTemplate",
"when": "explorerResourceIsFolder",
"group": "frontmatter@1"
@@ -2456,7 +2596,8 @@
"group": "frontmatter@3"
}
],
"commandPalette": [{
"commandPalette": [
{
"command": "frontMatter.init",
"when": "frontMatterCanInit"
},
@@ -2633,28 +2774,34 @@
"when": "frontMatter:file:isValid == true"
}
],
"view/title": [{
"view/title": [
{
"command": "frontMatter.docs",
"group": "navigation@-1",
"when": "view == frontMatter.explorer"
},
{
"command": "frontMatter.chatbot",
"group": "navigation@0",
"when": "view == frontMatter.explorer"
},
{
"command": "frontMatter.collapseSections",
"group": "navigation@1",
"when": "view == frontMatter.explorer"
},
{
"command": "frontMatter.mode.switch",
"group": "navigation@2",
"group": "navigation@1",
"when": "view == frontMatter.explorer && frontMatter:has:modes == true"
},
{
"command": "frontMatter.project.switch",
"group": "navigation@3",
"group": "navigation@2",
"when": "view == frontMatter.explorer && frontMatter:project:switch:enabled"
},
{
"command": "frontMatter.settings.refresh",
"group": "navigation@3",
"when": "view == frontMatter.explorer"
},
{
"command": "frontMatter.collapseSections",
"group": "navigation@4",
"when": "view == frontMatter.explorer"
},
@@ -2665,13 +2812,16 @@
}
]
},
"languages": [{
"id": "frontmatter.project.output",
"mimetypes": [
"text/x-code-output"
]
}],
"grammars": [{
"languages": [
{
"id": "frontmatter.project.output",
"mimetypes": [
"text/x-code-output"
]
}
],
"grammars": [
{
"path": "./syntaxes/hugo.tmLanguage.json",
"scopeName": "frontmatter.markdown.hugo",
"injectTo": [
@@ -2684,45 +2834,48 @@
"path": "./syntaxes/frontmatter-output.tmLanguage.json"
}
],
"walkthroughs": [{
"id": "frontmatter.welcome",
"title": "Get started with Front Matter",
"description": "Discover the features of Front Matter and learn how to use the CMS for your SSG or static site.",
"steps": [{
"id": "frontmatter.welcome.init",
"title": "Get started",
"description": "Initial steps to get started.\n[Open dashboard](command:frontMatter.dashboard)",
"media": {
"markdown": "assets/walkthrough/get-started.md"
"walkthroughs": [
{
"id": "frontmatter.welcome",
"title": "Get started with Front Matter",
"description": "Discover the features of Front Matter and learn how to use the CMS for your SSG or static site.",
"steps": [
{
"id": "frontmatter.welcome.init",
"title": "Get started",
"description": "Initial steps to get started.\n[Open dashboard](command:frontMatter.dashboard)",
"media": {
"markdown": "assets/walkthrough/get-started.md"
},
"completionEvents": [
"onContext:frontMatterInitialized"
]
},
"completionEvents": [
"onContext:frontMatterInitialized"
]
},
{
"id": "frontmatter.welcome.documentation",
"title": "Documentation",
"description": "Check out the documentation for Front Matter.\n[View our documentation](https://frontmatter.codes/docs)",
"media": {
"markdown": "assets/walkthrough/documentation.md"
{
"id": "frontmatter.welcome.documentation",
"title": "Documentation",
"description": "Check out the documentation for Front Matter.\n[View our documentation](https://frontmatter.codes/docs)",
"media": {
"markdown": "assets/walkthrough/documentation.md"
},
"completionEvents": [
"onLink:https://frontmatter.codes/docs"
]
},
"completionEvents": [
"onLink:https://frontmatter.codes/docs"
]
},
{
"id": "frontmatter.welcome.supporter",
"title": "Support the project",
"description": "Become a supporter.\n[Support the project](https://github.com/sponsors/estruyf)",
"media": {
"markdown": "assets/walkthrough/support-the-project.md"
},
"completionEvents": [
"onLink:https://github.com/sponsors/estruyf"
]
}
]
}]
{
"id": "frontmatter.welcome.supporter",
"title": "Support the project",
"description": "Become a supporter.\n[Support the project](https://github.com/sponsors/estruyf)",
"media": {
"markdown": "assets/walkthrough/support-the-project.md"
},
"completionEvents": [
"onLink:https://github.com/sponsors/estruyf"
]
}
]
}
]
},
"scripts": {
"dev:ext": "npm run clean && npm run localization:generate && npm-run-all --parallel watch:*",
@@ -2753,6 +2906,7 @@
"@heroicons/react": "^2.1.1",
"@iarna/toml": "2.2.3",
"@octokit/rest": "^18.12.0",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@sentry/react": "^6.19.7",
"@sentry/tracing": "^6.19.7",
"@tailwindcss/forms": "^0.5.3",
@@ -2768,12 +2922,11 @@
"@types/react": "17.0.0",
"@types/react-datepicker": "^4.8.0",
"@types/react-dom": "17.0.0",
"@types/vscode": "^1.73.0",
"@types/vscode": "^1.90.0",
"@types/webpack-bundle-analyzer": "^4.7.0",
"@typescript-eslint/eslint-plugin": "^5.50.0",
"@typescript-eslint/parser": "^5.50.0",
"@vscode-elements/elements": "^1.2.0",
"@vscode/l10n": "^0.0.14",
"@vscode/webview-ui-toolkit": "^1.2.2",
"@webpack-cli/serve": "^1.7.0",
"ajv": "^8.12.0",
"array-move": "^4.0.0",
@@ -2782,10 +2935,12 @@
"cheerio": "1.0.0-rc.12",
"clsx": "^2.1.0",
"css-loader": "5.2.7",
"date-fns": "2.23.0",
"date-fns": "^4.1.0",
"date-fns-tz": "^3.2.0",
"dotenv": "^16.3.1",
"downshift": "6.0.6",
"eslint": "^8.33.0",
"eslint-webpack-plugin": "^4.2.0",
"fuse.js": "6.5.3",
"github-directory-downloader": "^1.3.6",
"glob": "^10.3.12",
@@ -2819,8 +2974,16 @@
"react-quill": "^2.0.0",
"react-router-dom": "^6.8.0",
"react-sortable-hoc": "^2.0.0",
"react-tooltip": "^5.28.0",
"recoil": "^0.7.7",
"remark-gfm": "^3.0.1",
"rehype-parse": "^9.0.1",
"rehype-remark": "^10.0.0",
"rehype-stringify": "^10.0.1",
"remark": "^15.0.1",
"remark-gfm": "^4.0.0",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.1",
"remark-stringify": "^11.0.0",
"rimraf": "^3.0.2",
"semver": "^7.3.8",
"simple-git": "^3.16.0",
@@ -2830,24 +2993,24 @@
"tailwindcss-animate": "^1.0.7",
"ts-loader": "^9.4.2",
"typescript": "^4.9.5",
"unified": "^11.0.5",
"uniforms": "^3.10.2",
"uniforms-antd": "^3.10.2",
"uniforms-bridge-json-schema": "^3.10.2",
"uniforms-unstyled": "^3.10.2",
"url-join-ts": "^1.0.5",
"vscrui": "^0.1.0-beta.1094721",
"wc-react": "github:estruyf/wc-react",
"webpack": "^5.75.0",
"webpack-bundle-analyzer": "^4.7.0",
"webpack-bundle-analyzer": "^4.10.2",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1",
"webpack-ignore-dynamic-require": "^1.0.0",
"webpack-manifest-plugin": "^5.0.0",
"yaml": "^2.2.1",
"yawn-yaml": "^1.5.0"
},
"vsce": {
"dependencies": false
},
"dependencies": {
"@radix-ui/react-dropdown-menu": "^2.0.6"
}
}
}

View File

@@ -73,11 +73,13 @@
"setting.frontMatter.content.pageFolders.items.properties.path.description": "フォルダーのパス",
"setting.frontMatter.content.pageFolders.items.properties.excludeSubdir.description": "サブディレクトリを除外する",
"setting.frontMatter.content.pageFolders.items.properties.previewPath.description": "フォルダーのカスタム プレビュー パスを定義します。",
"setting.frontMatter.content.pageFolders.items.properties.trailingSlash.description": "プレビュー用URLに末尾のスラッシュを加えるかどうかを設定します。",
"setting.frontMatter.content.pageFolders.items.properties.filePrefix.description": "ファイル名の接頭辞を定義します。",
"setting.frontMatter.content.pageFolders.items.properties.contentTypes.description": "現在の場所に使用できる記事タイプを定義します。定義しない場合は、全ての記事タイプを使用できます。",
"setting.frontMatter.content.pageFolders.items.properties.disableCreation.description": "フォルダー内の新しい記事の作成を無効にします。",
"setting.frontMatter.content.pageFolders.items.properties.defaultLocale.description": "ページフォルダー用デフォルトのロケールIDを設定します。このフォルダー内の全ての記事が`frontMatter.content.i18n`で設定された言語へ翻訳可能になります。",
"setting.frontMatter.content.pageFolders.items.properties.locales.description": "ページフォルダーで利用するロケールを設定します。この設定は記事の翻訳に使用されます。",
"setting.frontMatter.content.pageFolders.items.properties.slugTemplate.description": "カスタムスラッグのテンプレートを定義します。",
"setting.frontMatter.content.i18n.markdownDescription": "ウェブサイトで利用するロケールを設定します。この設定はページフォルダーレベルの設定より優先されます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.content.i18n)",
"setting.frontMatter.content.i18n.items.properties.title.description": "言語名",
"setting.frontMatter.content.i18n.items.properties.locale.description": "言語コード",
@@ -175,6 +177,7 @@
"setting.frontMatter.panel.freeform.markdownDescription": "未登録のタグ/カテゴリーをタグピッカーに入力可能にするかどうかを設定します有効にすると、後で保存するオプションが使えます。規定値はtrue。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.freeform)",
"setting.frontMatter.panel.actions.disabled.markdownDescription": "パネル内で非表示にしたいコマンドを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.actions.disabled)",
"setting.frontMatter.preview.host.markdownDescription": "プレビュー表示に使用するホストのURLを設定します`http://localhost:1313`)。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.host)",
"setting.frontMatter.preview.trailingSlash.markdownDescription": "プレビュー用URLに末尾のスラッシュを加えるかどうかを設定します。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.trailingslash)",
"setting.frontMatter.preview.pathName.markdownDescription": "ホストパスとスラッグの間に追加したいパスを設定します。例えば、パスに`yyyy/MM`などの日付を含めたい場合等に使えます。日付は記事の日付フィールドの値に基づいて生成されます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.pathname)",
"setting.frontMatter.site.baseURL.markdownDescription": "ベースURLを設定します。これはSEOチェックに利用されます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.site.baseurl)",
"setting.frontMatter.taxonomy.alignFilename.markdownDescription": "ファイル生成時にファイル名をスラッグに合わせます。[ドキュメントを確認](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.alignfilename)",
@@ -229,6 +232,7 @@
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.caseSensitive.description": "比較で大文字と小文字を区別するかどうかを指定します。デフォルト: true",
"setting.frontMatter.taxonomy.contentTypes.items.properties.pageBundle.description": "新しい記事を作成するときにフォルダーを作成するかどうかを指定します。",
"setting.frontMatter.taxonomy.contentTypes.items.properties.previewPath.description": "記事タイプのカスタム プレビュー パスを定義します。",
"setting.frontMatter.taxonomy.contentTypes.items.properties.trailingSlash.description": "プレビュー用URLに末尾のスラッシュを加えるかどうかを設定します。",
"setting.frontMatter.taxonomy.contentTypes.items.properties.slugTemplate.description": "記事タイプのカスタムスラッグのテンプレートを設定します。",
"setting.frontMatter.taxonomy.contentTypes.items.properties.template.description": "新しい記事の作成に使用できるオプションのテンプレート。",
"setting.frontMatter.taxonomy.contentTypes.items.properties.postScript.description": "新しい記事の作成後に使用できるオプションのポストスクリプト。",

View File

@@ -38,6 +38,7 @@
"command.frontMatter.markup.orderedlist": "Ordered list",
"command.frontMatter.markup.options": "Other markup options",
"command.frontMatter.preview": "Preview content",
"command.frontMatter.docs": "Documentation",
"command.frontMatter.chatbot": "Ask the Front Matter AI for help",
"command.frontMatter.promoteSettings": "Promote settings from local to team level",
"command.frontMatter.remap": "Remap or remove tag/category in all articles",
@@ -49,29 +50,31 @@
"command.frontMatter.git.sync": "Sync",
"command.frontMatter.cache.clear": "Clear cache",
"command.frontMatter.i18n.create": "Create new translation",
"command.frontMatter.i18n.createOrOpen": "Create or open translation",
"settings.configuration.title": "Front Matter: use frontmatter.json for shared team settings",
"setting.frontMatter.projects.markdownDescription": "Specify the list of projects to load in the Front Matter CMS. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.projects)",
"setting.frontMatter.projects.markdownDescription": "Specify the list of projects to load in the Front Matter CMS. [Local](https://file%2B.vscode-resource.vscode-cdn.net/Users/eliostruyf/nodejs/frontmatter-test-projects/astro-blog/test.html) - [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.projects) - [View in VS Code](vscode://simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.projects%22%5D)",
"setting.frontMatter.projects.items.properties.name.markdownDescription": "Specify the name of the project.",
"setting.frontMatter.projects.items.properties.default.markdownDescription": "Specify if this project is the default project to load.",
"setting.frontMatter.sponsors.ai.enabled.markdownDescription": "Specify if you want to enable AI suggestions. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.sponsors.ai.enabled)",
"setting.frontMatter.extensibility.scripts.markdownDescription": "Specify the list of scripts to load in the Front Matter CMS. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.extensibility.scripts)",
"setting.frontMatter.experimental.markdownDescription": "Specify if you want to enable the experimental features. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.experimental)",
"setting.frontMatter.extends.markdownDescription": "Specify the list of paths/URLs to extend the Front Matter CMS config. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.extends)",
"setting.frontMatter.content.autoUpdateDate.markdownDescription": "Specify if you want to automatically update the modified date of your article/page (only content located in your content folder). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.autoupdatedate)",
"setting.frontMatter.content.defaultFileType.markdownDescription": "Specify the default file type for the content to create. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultfiletype)",
"setting.frontMatter.content.defaultSorting.markdownDescription": "Specify the default sorting option for the content dashboard. You can use one of the values from the enum or define your own ID. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultsorting)",
"setting.frontMatter.content.draftField.markdownDescription": "Define the draft field you want to use to manage your content. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.draftfield)",
"setting.frontMatter.sponsors.ai.enabled.markdownDescription": "Specify if you want to enable AI suggestions. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.sponsors.ai.enabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.sponsors.ai.enabled%22%5D)",
"setting.frontMatter.extensibility.scripts.markdownDescription": "Specify the list of scripts to load in the Front Matter CMS. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.extensibility.scripts) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.extensibility.scripts%22%5D)",
"setting.frontMatter.experimental.markdownDescription": "Specify if you want to enable the experimental features. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.experimental) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.experimental%22%5D)",
"setting.frontMatter.extends.markdownDescription": "Specify the list of paths/URLs to extend the Front Matter CMS config. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.extends) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.extends%22%5D)",
"setting.frontMatter.content.autoUpdateDate.markdownDescription": "Specify if you want to automatically update the modified date of your article/page (only content located in your content folder). [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.autoupdatedate) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.autoupdatedate%22%5D)",
"setting.frontMatter.content.defaultFileType.markdownDescription": "Specify the default file type for the content to create. [Docs](https://frontmatter.codes/docs/settings/overview%23frontmatter.content.defaultfiletype) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.defaultfiletype%22%5D)",
"setting.frontMatter.content.defaultSorting.markdownDescription": "Specify the default sorting option for the content dashboard. You can use one of the values from the enum or define your own ID. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.defaultsorting) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.defaultsorting%22%5D)",
"setting.frontMatter.content.draftField.markdownDescription": "Define the draft field you want to use to manage your content. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.draftfield) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.draftfield%22%5D)",
"setting.frontMatter.content.draftField.properties.type.description": "Type of the draft field you want to use",
"setting.frontMatter.content.draftField.properties.name.description": "Name of the field to use",
"setting.frontMatter.content.draftField.properties.invert.description": "By default the draft field is set to true when the content is a draft. Set this to true to set it to false.",
"setting.frontMatter.content.draftField.properties.choices.description": "List of choices for the field",
"setting.frontMatter.content.fmHighlight.markdownDescription": "Specify if you want to highlight the Front Matter in the Markdown file. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.fmhighlight)",
"setting.frontMatter.content.hideFm.markdownDescription": "Specify if you want to hide the Front Matter in the Markdown file. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefm)",
"setting.frontMatter.content.hideFmMessage.markdownDescription": "Specify the message to display when the Front Matter is hidden. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefmMessage)",
"setting.frontMatter.content.pageFolders.markdownDescription": "This array of folders defines where the extension can retrieve or create new pages. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.pagefolders)",
"setting.frontMatter.content.fmHighlight.markdownDescription": "Specify if you want to highlight the Front Matter in the Markdown file. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.fmhighlight) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.fmhighlight%22%5D)",
"setting.frontMatter.content.hideFm.markdownDescription": "Specify if you want to hide the Front Matter in the Markdown file. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefm) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.hidefm%22%5D)",
"setting.frontMatter.content.hideFmMessage.markdownDescription": "Specify the message to display when the Front Matter is hidden. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.hidefmMessage) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.hidefmMessage%22%5D)",
"setting.frontMatter.content.pageFolders.markdownDescription": "This array of folders defines where the extension can retrieve or create new pages. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.pagefolders) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.pagefolders%22%5D)",
"setting.frontMatter.content.pageFolders.items.properties.title.description": "Name of the folder",
"setting.frontMatter.content.pageFolders.items.properties.path.description": "Path of the folder",
"setting.frontMatter.content.pageFolders.items.properties.excludeSubdir.description": "Exclude sub-directories",
"setting.frontMatter.content.pageFolders.items.properties.excludePaths.description": "Exclude paths (e.g. api, _*.*)",
"setting.frontMatter.content.pageFolders.items.properties.previewPath.description": "Defines a custom preview path for the folder.",
"setting.frontMatter.content.pageFolders.items.properties.trailingSlash.description": "Specify if you want to add a trailing slash to the preview URL.",
"setting.frontMatter.content.pageFolders.items.properties.filePrefix.description": "Defines a prefix for the file name.",
@@ -80,29 +83,33 @@
"setting.frontMatter.content.pageFolders.items.properties.defaultLocale.description": "Set the default locale ID for the page folder. All content from this folder is translatable to the languages defined in the `frontMatter.content.i18n` setting.",
"setting.frontMatter.content.pageFolders.items.properties.locales.description": "Define the locales for the page folder. This will be used for the translation of the content.",
"setting.frontMatter.content.pageFolders.items.properties.slugTemplate.description": "Defines a custom slug template.",
"setting.frontMatter.content.i18n.markdownDescription": "Specify the locales you want to use for your website. This setting can be overwritten on page folder level. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.i18n)",
"setting.frontMatter.content.i18n.markdownDescription": "Specify the locales you want to use for your website. This setting can be overwritten on page folder level. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.i18n) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.i18n%22%5D)",
"setting.frontMatter.content.i18n.items.properties.title.description": "Title of the locale",
"setting.frontMatter.content.i18n.items.properties.locale.description": "Locale code",
"setting.frontMatter.content.i18n.items.properties.path.description": "Relative path of the locale folder",
"setting.frontMatter.content.placeholders.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/overview#frontmatter.content.placeholders)",
"setting.frontMatter.content.placeholders.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. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.placeholders) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.placeholders%22%5D)",
"setting.frontMatter.content.placeholders.items.properties.id.description": "ID of the placeholder, in your content type or template, use it as follows: {{placeholder}}",
"setting.frontMatter.content.placeholders.items.properties.value.description": "The placeholder its value",
"setting.frontMatter.content.placeholders.items.properties.script.description": "The script to execute to get the value of the placeholder",
"setting.frontMatter.content.publicFolder.markdownDescription": "Specify the folder name where all your assets are located. For instance in Hugo this is the `static` folder. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.publicfolder)",
"setting.frontMatter.content.publicFolder.markdownDescription": "Specify the folder name where all your assets are located. For instance in Hugo this is the `static` folder. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.publicfolder) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.publicfolder%22%5D)",
"setting.frontMatter.content.publicFolder.properties.path.description": "Specify the path of the assets folder",
"setting.frontMatter.content.publicFolder.properties.relative.description": "Defines if the path to your media files be relative to the content file?",
"setting.frontMatter.snippets.wrapper.enabled.markdownDescription": "Specify if you want to wrap the snippets. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.snippets.wrapper.enabled)",
"setting.frontMatter.content.snippets.markdownDescription": "Define the snippets you want to use in your content. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.snippets)",
"setting.frontMatter.content.sorting.markdownDescription": "Define the sorting options for your dashboard content. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.sorting)",
"setting.frontMatter.snippets.wrapper.enabled.markdownDescription": "Specify if you want to wrap the snippets. [Docs](https://frontmatter.codes/docs/settings/overview#frontMatter.snippets.wrapper.enabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontMatter.snippets.wrapper.enabled%22%5D)",
"setting.frontMatter.content.snippets.markdownDescription": "Define the snippets you want to use in your content. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.snippets) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.snippets%22%5D)",
"setting.frontMatter.content.grouping.markdownDescription": "Specify the grouping options for your dashboard content. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.grouping) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.grouping%22%5D)",
"setting.frontMatter.content.grouping.items.properties.id.description": "The ID of the grouping option.",
"setting.frontMatter.content.grouping.items.properties.title.description": "Title of the grouping which will be shown in the UI.",
"setting.frontMatter.content.grouping.items.properties.name.description": "Name of the content-type field to group by.",
"setting.frontMatter.content.sorting.markdownDescription": "Define the sorting options for your dashboard content. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.sorting) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.sorting%22%5D)",
"setting.frontMatter.content.sorting.items.properties.id.description": "The ID of the sorting option. This will be used for the storing the last used sorting option or the default option.",
"setting.frontMatter.content.sorting.items.properties.title.description": "Name of the sorting label",
"setting.frontMatter.content.sorting.items.properties.name.description": "Name of the metadata field to sort by",
"setting.frontMatter.content.sorting.items.properties.order.description": "Order of the sorting",
"setting.frontMatter.content.sorting.items.properties.type.description": "Type of the field value",
"setting.frontMatter.content.supportedFileTypes.markdownDescription": "Specify the file types that you want to use in Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.supportedfiletypes)",
"setting.frontMatter.content.wysiwyg.markdownDescription": "Specifies if you want to enable/disable the What You See, Is What You Get (WYSIWYG) markdown controls. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.wysiwyg)",
"setting.frontMatter.content.filters.markdownDescription": "Specify the filters you want to use for your content dashboard. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.filters)",
"setting.frontMatter.custom.scripts.markdownDescription": "Specify the path to a Node.js script to execute. The current file path will be provided as an argument. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.custom.scripts)",
"setting.frontMatter.content.supportedFileTypes.markdownDescription": "Specify the file types that you want to use in Front Matter. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.supportedfiletypes) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.supportedfiletypes%22%5D)",
"setting.frontMatter.content.wysiwyg.markdownDescription": "Specifies if you want to enable/disable the What You See, Is What You Get (WYSIWYG) markdown controls. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.wysiwyg) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.wysiwyg%22%5D)",
"setting.frontMatter.content.filters.markdownDescription": "Specify the filters you want to use for your content dashboard. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.content.filters) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.content.filters%22%5D)",
"setting.frontMatter.custom.scripts.markdownDescription": "Specify the path to a Node.js script to execute. The current file path will be provided as an argument. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.custom.scripts) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.custom.scripts%22%5D)",
"setting.frontMatter.custom.scripts.items.properties.id.description": "ID of the script.",
"setting.frontMatter.custom.scripts.items.properties.title.description": "Title you want to give to your script. Will be shown as the title of the button.",
"setting.frontMatter.custom.scripts.items.properties.script.description": "Path to the script to execute",
@@ -116,16 +123,16 @@
"setting.frontMatter.custom.scripts.items.properties.environments.items.properties.type.description": "The environment type for which the script needs to be used",
"setting.frontMatter.custom.scripts.items.properties.environments.items.properties.script.description": "Path to the script to execute",
"setting.frontMatter.custom.scripts.items.properties.contentTypes.description": "Define the content types for which the script will be used. If none are defined, it will be available to all types.",
"setting.frontMatter.dashboard.content.pagination.markdownDescription": "Specify if you want to enable/disable pagination for your content. You can define your page number up to 52. Default items per page is `16`. Disabling the pagination can be done by setting it to `false`. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.pagination)",
"setting.frontMatter.dashboard.content.cardTags.markdownDescription": "Specify the name of the metadata field that will be used to show the tags on the content card. When empty or null, it will hide the tags from the card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.cardtags)",
"setting.frontMatter.dashboard.content.card.fields.state.markdownDescription": "Specify if you want to show the state/draft status on the content card view. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.state)",
"setting.frontMatter.dashboard.content.card.fields.date.markdownDescription": "Specify if you want to show the date on the content card view. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.date)",
"setting.frontMatter.dashboard.content.card.fields.description.markdownDescription": "Specify the name of the metadata field that will be used to show the description on the content card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.description)",
"setting.frontMatter.dashboard.content.card.fields.title.markdownDescription": "Specify the name of the metadata field that will be used to show the title on the content card. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.title)",
"setting.frontMatter.dashboard.mediaSnippet.markdownDescription": "Specify the a snippet for your custom media insert markup. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.mediasnippet)",
"setting.frontMatter.dashboard.content.pagination.markdownDescription": "Specify if you want to enable/disable pagination for your content. You can define your page number up to 52. Default items per page is `16`. Disabling the pagination can be done by setting it to `false`. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.pagination) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.dashboard.content.pagination%22%5D)",
"setting.frontMatter.dashboard.content.cardTags.markdownDescription": "Specify the name of the metadata field that will be used to show the tags on the content card. When empty or null, it will hide the tags from the card. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.content.cardtags) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.dashboard.content.cardtags%22%5D)",
"setting.frontMatter.dashboard.content.card.fields.state.markdownDescription": "Specify if you want to show the state/draft status on the content card view. [Docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.state) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontMatter.dashboard.content.card.fields.state%22%5D)",
"setting.frontMatter.dashboard.content.card.fields.date.markdownDescription": "Specify if you want to show the date on the content card view. [Docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.date) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontMatter.dashboard.content.card.fields.date%22%5D)",
"setting.frontMatter.dashboard.content.card.fields.description.markdownDescription": "Specify the name of the metadata field that will be used to show the description on the content card. [Docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.description) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontMatter.dashboard.content.card.fields.description%22%5D)",
"setting.frontMatter.dashboard.content.card.fields.title.markdownDescription": "Specify the name of the metadata field that will be used to show the title on the content card. [Docs](https://frontmatter.codes/docs/settings/overview#frontMatter.dashboard.content.card.fields.title) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontMatter.dashboard.content.card.fields.title%22%5D)",
"setting.frontMatter.dashboard.mediaSnippet.markdownDescription": "Specify the a snippet for your custom media insert markup. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.mediasnippet) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.dashboard.mediasnippet%22%5D)",
"setting.frontMatter.dashboard.mediaSnippet.items.description": "Use the `{mediaUrl}`, `{caption}`, `{alt}`, `{filename}`, `{mediaHeight}`, and `{mediaWidth}` placeholders in your snippet to automatically insert the media information.",
"setting.frontMatter.dashboard.openOnStart.markdownDescription": "Specify if you want to open the dashboard when you start VS Code. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.openonstart)",
"setting.frontMatter.data.files.markdownDescription": "Specify the data files you want to use for your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.files)",
"setting.frontMatter.dashboard.openOnStart.markdownDescription": "Specify if you want to open the dashboard when you start VS Code. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.dashboard.openonstart) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.dashboard.openonstart%22%5D)",
"setting.frontMatter.data.files.markdownDescription": "Specify the data files you want to use for your website. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.files) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.data.files%22%5D)",
"setting.frontMatter.data.files.items.properties.id.description": "Your unique ID you want to use for your data file.",
"setting.frontMatter.data.files.items.properties.title.description": "Title you want to give to your data file.",
"setting.frontMatter.data.files.items.properties.labelField.description": "The field you want to use as label for your data entries.",
@@ -138,33 +145,36 @@
"setting.frontMatter.data.files.items.properties.schema.properties.properties.description": "Defines the fields of the form.",
"setting.frontMatter.data.files.items.properties.type.description": "If you are using data types, you can specify your type ID.",
"setting.frontMatter.data.files.items.properties.singleEntry.description": "If you want to use a single entry for your data file.",
"setting.frontMatter.data.folders.markdownDescription": "Specify the data folders you want to use for your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.folders)",
"setting.frontMatter.data.folders.markdownDescription": "Specify the data folders you want to use for your website. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.folders) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.data.folders%22%5D)",
"setting.frontMatter.data.folders.items.properties.id.description": "Your unique ID you want to use for your data folder.",
"setting.frontMatter.data.folders.items.properties.labelField.description": "The field you want to use as label for your data entries.",
"setting.frontMatter.data.folders.items.properties.path.description": "Path to the folder to load files.",
"setting.frontMatter.data.folders.items.properties.type.description": "If you are using data types, you can specify your type ID.",
"setting.frontMatter.data.folders.items.properties.singleEntry.description": "If you want to use a single entry for your data files in the folder.",
"setting.frontMatter.data.types.markdownDescription": "Specify the data types. These types can be used in for your data files. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.types)",
"setting.frontMatter.data.folders.items.properties.enableFileCreation.description": "Enable the creation of new data files in the folder.",
"setting.frontMatter.data.folders.items.properties.fileType.description": "Defines the file type for when the file creation is enabled. JSON is the default.",
"setting.frontMatter.data.types.markdownDescription": "Specify the data types. These types can be used in for your data files. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.data.types) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.data.types%22%5D)",
"setting.frontMatter.data.types.items.properties.id.description": "Your unique ID you want to use for your data type.",
"setting.frontMatter.file.preserveCasing.markdownDescription": "Specify if you want to preserve the casing of your file names from the title. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.file.preservecasing)",
"setting.frontMatter.framework.id.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/overview#frontmatter.framework.id)",
"setting.frontMatter.framework.startCommand.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/overview#frontmatter.framework.startcommand)",
"setting.frontMatter.git.enabled.markdownDescription": "Specify if you want to use the Git actions for your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.enabled)",
"setting.frontMatter.git.commitMessage.markdownDescription": "Specify the commit message you want to use for the sync. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.commitmessage)",
"setting.frontMatter.git.submodule.pull.markdownDescription": "Specify if you want to pull submodules when syncing. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.pull)",
"setting.frontMatter.git.submodule.push.markdownDescription": "Specify if you want to push submodules when syncing. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.push)",
"setting.frontMatter.git.submodule.branch.markdownDescription": "Specify the submodule branch to checkout. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.branch)",
"setting.frontMatter.git.submodule.folder.markdownDescription": "Specify the submodule folder of your content, this can be handy when you are using multiple submodules. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.folder)",
"setting.frontMatter.global.activeMode.markdownDescription": "Specify the activated mode of Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.activemode)",
"setting.frontMatter.global.modes.markdownDescription": "Specify the modes you want to use for Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.modes)",
"setting.frontMatter.file.preserveCasing.markdownDescription": "Specify if you want to preserve the casing of your file names from the title. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.file.preservecasing) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.file.preservecasing%22%5D)",
"setting.frontMatter.framework.id.markdownDescription": "Specify the ID of your static site generator or framework you are using for your website. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.id) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.framework.id%22%5D)",
"setting.frontMatter.framework.startCommand.markdownDescription": "Specify the command you want to use to start your static site generator or framework. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.framework.startcommand) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.framework.startcommand%22%5D)",
"setting.frontMatter.git.enabled.markdownDescription": "Specify if you want to use the Git actions for your website. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.enabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.enabled%22%5D)",
"setting.frontMatter.git.commitMessage.markdownDescription": "Specify the commit message you want to use for the sync. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.commitmessage) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.commitmessage%22%5D)",
"setting.frontMatter.git.submodule.pull.markdownDescription": "Specify if you want to pull submodules when syncing. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.pull) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.submodule.pull%22%5D)",
"setting.frontMatter.git.submodule.push.markdownDescription": "Specify if you want to push submodules when syncing. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.push) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.submodule.push%22%5D)",
"setting.frontMatter.git.submodule.branch.markdownDescription": "Specify the submodule branch to checkout. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.branch) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.submodule.branch%22%5D)",
"setting.frontMatter.git.submodule.folder.markdownDescription": "Specify the submodule folder of your content, this can be handy when you are using multiple submodules. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.submodule.folder) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.submodule.folder%22%5D)",
"setting.frontMatter.global.activeMode.markdownDescription": "Specify the activated mode of Front Matter. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.activemode) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.global.activemode%22%5D)",
"setting.frontMatter.global.modes.markdownDescription": "Specify the modes you want to use for Front Matter. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.modes) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.global.modes%22%5D)",
"setting.frontMatter.global.modes.items.properties.id.description": "The ID of your mode.",
"setting.frontMatter.global.modes.items.properties.features.description": "The features you want to use for your mode.",
"setting.frontMatter.global.notifications.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/overview#frontmatter.global.notifications)",
"setting.frontMatter.global.disabledNotifications.markdownDescription": "This is an array with the notifications types that can be disabled for Front Matter CMS. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.disablednotifications)",
"setting.frontMatter.media.defaultSorting.markdownDescription": "Specify the default sorting option for the media dashboard. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.media.defaultsorting)",
"setting.frontMatter.media.supportedMimeTypes.markdownDescription": "Specify the mime types to support for the media files. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.media.supportedmimetypes)",
"setting.frontMatter.global.notifications.markdownDescription": "Specifies the notifications you want to see. By default, all notifications types will be shown. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.notifications) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.global.notifications%22%5D)",
"setting.frontMatter.global.disabledNotifications.markdownDescription": "This is an array with the notifications types that can be disabled for Front Matter CMS. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.global.disablednotifications) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.global.disablednotifications%22%5D)",
"setting.frontMatter.global.timezone.markdownDescription": "Specify the timezone for your date formatting. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.datetimezone) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.datetimezone%22%5D)",
"setting.frontMatter.media.defaultSorting.markdownDescription": "Specify the default sorting option for the media dashboard. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.media.defaultsorting) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.media.defaultsorting%22%5D)",
"setting.frontMatter.media.supportedMimeTypes.markdownDescription": "Specify the mime types to support for the media files. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.media.supportedmimetypes) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.media.supportedmimetypes%22%5D)",
"setting.frontMatter.media.contentTypes.markdownDescription": "Specify the media content types you want to use in Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.media.contenttypes)",
"setting.frontMatter.media.contentTypes.markdownDescription": "Specify the media content types you want to use in Front Matter. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.media.contenttypes) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.media.contenttypes%22%5D)",
"setting.frontMatter.media.contentTypes.items.description": "Define the media content types you want to use in Front Matter.",
"setting.frontMatter.media.contentTypes.items.properties.name.description": "Name of the media content type",
"setting.frontMatter.media.contentTypes.items.properties.fileTypes.description": "Specify the file types to allow for the media content type",
@@ -174,17 +184,18 @@
"setting.frontMatter.media.contentTypes.items.properties.fields.properties.type.description": "Define the type of field",
"setting.frontMatter.media.contentTypes.items.properties.fields.properties.single.description": "Is a single line field",
"setting.frontMatter.panel.freeform.markdownDescription": "Specifies if you want to allow yourself from entering unknown tags/categories in the tag picker (when enabled, you will have the option to store them afterwards). Default: true. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.freeform)",
"setting.frontMatter.panel.actions.disabled.markdownDescription": "Specify the actions you want to disable in the panel. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.actions.disabled)",
"setting.frontMatter.preview.host.markdownDescription": "Specify the host URL (example: http://localhost:1313) to be used when opening the preview. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.host)",
"setting.frontMatter.preview.trailingSlash.markdownDescription": "Specify if you want to add a trailing slash to the preview URL. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.trailingslash)",
"setting.frontMatter.preview.pathName.markdownDescription": "Specify the path you want to add after the host and before your slug. This can be used for instance to include the year/month like: `yyyy/MM`. The date will be generated based on the article its date field value. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.pathname)",
"setting.frontMatter.site.baseURL.markdownDescription": "Specify the base URL of your site, this will be used for SEO checks. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.site.baseurl)",
"setting.frontMatter.taxonomy.alignFilename.markdownDescription": "Align the filename with the new slug when it gets generated. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.alignfilename)",
"setting.frontMatter.taxonomy.categories.markdownDescription": "Specifies the categories which can be used in the Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.categories)",
"setting.frontMatter.taxonomy.commaSeparatedFields.markdownDescription": "Specify the fields names that Front Matter should treat as a comma-separated array. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.commaseparatedfields)",
"setting.frontMatter.panel.openOnSupportedFile.markdownDescription": "Specifies if you want to open the panel when opening a supported file. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.openonsupportedfile) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.panel.openonsupportedfile%22%5D)",
"setting.frontMatter.panel.freeform.markdownDescription": "Specifies if you want to allow yourself from entering unknown tags/categories in the tag picker (when enabled, you will have the option to store them afterwards). Default: true. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.freeform) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.panel.freeform%22%5D)",
"setting.frontMatter.panel.actions.disabled.markdownDescription": "Specify the actions you want to disable in the panel. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.panel.actions.disabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.panel.actions.disabled%22%5D)",
"setting.frontMatter.preview.host.markdownDescription": "Specify the host URL (example: http://localhost:1313) to be used when opening the preview. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.host) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.preview.host%22%5D)",
"setting.frontMatter.preview.trailingSlash.markdownDescription": "Specify if you want to add a trailing slash to the preview URL. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.trailingslash) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.preview.trailingslash%22%5D)",
"setting.frontMatter.preview.pathName.markdownDescription": "Specify the path you want to add after the host and before your slug. This can be used for instance to include the year/month like: `yyyy/MM`. The date will be generated based on the article its date field value. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.preview.pathname) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.preview.pathname%22%5D)",
"setting.frontMatter.site.baseURL.markdownDescription": "Specify the base URL of your site, this will be used for SEO checks. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.site.baseurl) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.site.baseurl%22%5D)",
"setting.frontMatter.taxonomy.alignFilename.markdownDescription": "Align the filename with the new slug when it gets generated. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.alignfilename) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.alignfilename%22%5D)",
"setting.frontMatter.taxonomy.categories.markdownDescription": "Specifies the categories which can be used in the Front Matter. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.categories) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.categories%22%5D)",
"setting.frontMatter.taxonomy.commaSeparatedFields.markdownDescription": "Specify the fields names that Front Matter should treat as a comma-separated array. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.commaseparatedfields) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.commaseparatedfields%22%5D)",
"setting.frontMatter.taxonomy.commaSeparatedFields.items.description": "Name of the fields you want to use as comma-separated arrays.",
"setting.frontMatter.taxonomy.contentTypes.markdownDescription": "Specify the type of contents you want to use for your articles/pages/etc. Make sure the `type` is correctly set in your front matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.contenttypes)",
"setting.frontMatter.taxonomy.contentTypes.markdownDescription": "Specify the type of contents you want to use for your articles/pages/etc. Make sure the `type` is correctly set in your front matter. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.contenttypes) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.contenttypes%22%5D)",
"setting.frontMatter.taxonomy.contentTypes.items.description": "Define the content types you want to use in Front Matter.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.name.description": "Define the type of field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fileType.description": "Specifies the type of content you want to create.",
@@ -199,7 +210,7 @@
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.items.properties.id.description": "The choice ID",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.choices.items.properties.title.description": "The choice title",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.single.description": "Is a single line field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.wysiwyg.description": "Is a WYSIWYG field (HTML output)",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.wysiwyg.description": "Is a WYSIWYG field. You can set it to markdown or HTML.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.multiple.description": "Do you allow to select multiple values?",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.isPreviewImage.description": "Specify if the image field can be used as preview. Be aware, you can only have one preview image per content type.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.hidden.description": "Do you want to hide the field from the metadata section?",
@@ -225,11 +236,13 @@
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.required.description": "Specify if the field is required",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeName.description": "Specify the content type name to filter content for the contentRelationship field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.contentTypeValue.description": "Specify the value to insert for the contentRelationship field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.sameContentLocale.description": "Specify if you only want to show the content with the same locale",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.description": "Specify the conditions to show the field",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.fieldRef.description": "The field ID to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.operator.description": "The operator to use",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.value.description": "The value to compare",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.when.properties.caseSensitive.description": "Specify if the comparison is case sensitive. Default: true",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.actions.description": "Specify the field custom actions",
"setting.frontMatter.taxonomy.contentTypes.items.properties.pageBundle.description": "Specify if you want to create a folder when creating new content.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.previewPath.description": "Defines a custom preview path for the content type.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.trailingSlash.description": "Specify if you want to add a trailing slash to the preview URL.",
@@ -238,45 +251,46 @@
"setting.frontMatter.taxonomy.contentTypes.items.properties.postScript.description": "An optional post script that can be used after new content creation.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.filePrefix.description": "Defines a prefix for the file name.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.defaultFileName.description": "Default file name to use when creating new content.",
"setting.frontMatter.taxonomy.customTaxonomy.markdownDescription": "Specify the custom taxonomy field data. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags)",
"setting.frontMatter.taxonomy.customTaxonomy.markdownDescription": "Specify the custom taxonomy field data. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.tags%22%5D)",
"setting.frontMatter.taxonomy.customTaxonomy.items.properties.id.description": "ID for your taxonomy field. It cannot contain the \"tags\" or \"categories\" value.",
"setting.frontMatter.taxonomy.customTaxonomy.items.properties.options.description": "Options from which you can pick.",
"setting.frontMatter.taxonomy.dateField.markdownDescription": "This setting is used to define the publishing date field of your articles. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.datefield)",
"setting.frontMatter.taxonomy.dateFormat.markdownDescription": "Specify the date format for your articles. Check [date-fns formating](https://date-fns.org/v2.0.1/docs/format) for more information. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.dateformat)",
"setting.frontMatter.taxonomy.fieldGroups.markdownDescription": "Define the field groups you want to use for your block fields or collection fields. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.fieldgroups)",
"setting.frontMatter.taxonomy.dateField.markdownDescription": "This setting is used to define the publishing date field of your articles. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.datefield) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.datefield%22%5D)",
"setting.frontMatter.taxonomy.dateFormat.markdownDescription": "Specify the date format for your articles. Check [date-fns formating](https://date-fns.org/v2.0.1/docs/format) for more information. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.dateformat) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.dateformat%22%5D)",
"setting.frontMatter.taxonomy.fieldGroups.markdownDescription": "Define the field groups you want to use for your block fields or collection fields. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.fieldgroups) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.fieldgroups%22%5D)",
"setting.frontMatter.taxonomy.fieldGroups.items.properties.id.description": "The name of the field group",
"setting.frontMatter.taxonomy.fieldGroups.items.properties.labelField.description": "The name of the field to be used as display value",
"setting.frontMatter.taxonomy.frontMatterType.markdownDescription": "Specify the type of Front Matter to use. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.frontmattertype)",
"setting.frontMatter.taxonomy.indentArrays.markdownDescription": "Specify if arrays in front matter are indented. Default: true. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.indentarrays)",
"setting.frontMatter.taxonomy.modifiedField.markdownDescription": "This setting is used to define the modified date field of your articles. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.modifiedfield)",
"setting.frontMatter.taxonomy.quoteStringValues.markdownDescription": "Specify if you want to quote string values in the front matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.quotestringvalues)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.markdownDescription": "Specify the properties from which quotes need to be removed. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.nopropertyvaluequotes)",
"setting.frontMatter.taxonomy.frontMatterType.markdownDescription": "Specify the type of Front Matter to use. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.frontmattertype) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.frontmattertype%22%5D)",
"setting.frontMatter.taxonomy.indentArrays.markdownDescription": "Specify if arrays in front matter are indented. Default: true. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.indentarrays) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.indentarrays%22%5D)",
"setting.frontMatter.taxonomy.modifiedField.markdownDescription": "This setting is used to define the modified date field of your articles. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.modifiedfield) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.modifiedfield%22%5D)",
"setting.frontMatter.taxonomy.quoteStringValues.markdownDescription": "Specify if you want to quote string values in the front matter. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.quotestringvalues) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.quotestringvalues%22%5D)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.markdownDescription": "Specify the properties from which quotes need to be removed. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.nopropertyvaluequotes) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.nopropertyvaluequotes%22%5D)",
"setting.frontMatter.taxonomy.noPropertyValueQuotes.items.description": "Name of the properties you want to remove quotes from.",
"setting.frontMatter.taxonomy.seoContentLengh.markdownDescription": "Specifies the optimal minimum length for your articles. Between 1,760 words 2,400 is the absolute ideal article length for SEO in 2021. (set to `-1` to turn it off). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seocontentlengh)",
"setting.frontMatter.taxonomy.seoDescriptionField.markdownDescription": "Specifies the name of the SEO description field for your page. Default is 'description'. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionfield)",
"setting.frontMatter.taxonomy.seoDescriptionLength.markdownDescription": "Specifies the optimal description length for SEO (set to `-1` to turn it off). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionlength)",
"setting.frontMatter.taxonomy.seoSlugLength.markdownDescription": "Specifies the optimal slug length for SEO (set to `-1` to turn it off). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seosluglength)",
"setting.frontMatter.taxonomy.seoTitleField.markdownDescription": "Specifies the name of the SEO title field for your page. Default is 'title'. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlefield)",
"setting.frontMatter.taxonomy.seoTitleLength.markdownDescription": "Specifies the optimal title length for SEO (set to `-1` to turn it off). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlelength)",
"setting.frontMatter.taxonomy.slugPrefix.markdownDescription": "Specify a prefix for the slug. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugprefix)",
"setting.frontMatter.taxonomy.slugSuffix.markdownDescription": "Specify a suffix for the slug. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugsuffix)",
"setting.frontMatter.taxonomy.slugTemplate.markdownDescription": "Defines a custom slug template for the content you will create. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugtemplate)",
"setting.frontMatter.taxonomy.tags.markdownDescription": "Specifies the tags which can be used in the Front Matter. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags)",
"setting.frontMatter.telemetry.disable.markdownDescription": "Specify if you want to disable the telemetry. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.telemetry.disable)",
"setting.frontMatter.templates.enabled.markdownDescription": "Specify if you want to use templates. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.enabled)",
"setting.frontMatter.templates.folder.markdownDescription": "Specify the folder to use for your article templates. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.folder)",
"setting.frontMatter.templates.prefix.markdownDescription": "Specify the prefix you want to add for your new article filenames. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.prefix)",
"setting.frontMatter.taxonomy.seoContentLengh.markdownDescription": "Specifies the optimal minimum length for your articles. Between 1,760 words 2,400 is the absolute ideal article length for SEO in 2021. (set to `-1` to turn it off). [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seocontentlengh) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.seocontentlengh%22%5D)",
"setting.frontMatter.taxonomy.seoDescriptionField.markdownDescription": "Specifies the name of the SEO description field for your page. Default is 'description'. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionfield) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.seodescriptionfield%22%5D)",
"setting.frontMatter.taxonomy.seoDescriptionLength.markdownDescription": "Specifies the optimal description length for SEO (set to `-1` to turn it off). [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seodescriptionlength) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.seodescriptionlength%22%5D)",
"setting.frontMatter.taxonomy.seoSlugLength.markdownDescription": "Specifies the optimal slug length for SEO (set to `-1` to turn it off). [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seosluglength) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.seosluglength%22%5D)",
"setting.frontMatter.taxonomy.seoTitleField.markdownDescription": "Specifies the name of the SEO title field for your page. Default is 'title'. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlefield) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.seotitlefield%22%5D)",
"setting.frontMatter.taxonomy.seoTitleLength.markdownDescription": "Specifies the optimal title length for SEO (set to `-1` to turn it off). [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.seotitlelength) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.seotitlelength%22%5D)",
"setting.frontMatter.taxonomy.slugPrefix.markdownDescription": "Specify a prefix for the slug. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugprefix) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.slugprefix%22%5D)",
"setting.frontMatter.taxonomy.slugSuffix.markdownDescription": "Specify a suffix for the slug. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugsuffix) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.slugsuffix%22%5D)",
"setting.frontMatter.taxonomy.slugTemplate.markdownDescription": "Defines a custom slug template for the content you will create. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.slugtemplate) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.slugtemplate%22%5D)",
"setting.frontMatter.taxonomy.tags.markdownDescription": "Specifies the tags which can be used in the Front Matter. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.taxonomy.tags) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.taxonomy.tags%22%5D)",
"setting.frontMatter.telemetry.disable.markdownDescription": "Specify if you want to disable the telemetry. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.telemetry.disable) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.telemetry.disable%22%5D)",
"setting.frontMatter.templates.enabled.markdownDescription": "Specify if you want to use templates. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.enabled) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.templates.enabled%22%5D)",
"setting.frontMatter.templates.folder.markdownDescription": "Specify the folder to use for your article templates. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.folder) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.templates.folder%22%5D)",
"setting.frontMatter.templates.prefix.markdownDescription": "Specify the prefix you want to add for your new article filenames. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.templates.prefix) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.templates.prefix%22%5D)",
"setting.frontMatter.dashboard.mediaSnippet.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please define your media snippet in the `frontMatter.content.snippet` setting.",
"setting.frontMatter.taxonomy.dateField.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please use the new `isPublishDate` settings instead in your content types date fields.",
"setting.frontMatter.taxonomy.modifiedField.deprecationMessage": "This setting is deprecated and will be removed in the next major version. Please use the new `isModifiedDate` settings instead in your content types date fields.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.fields.items.properties.customType.description": "Specify the name of the custom field type to use.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.clearEmpty.description": "Specify if the empty values should be cleared.",
"setting.frontMatter.website.host.markdownDescription": "Specify the host URL of your website. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.website.url)",
"setting.frontMatter.website.host.markdownDescription": "Specify the host URL of your website. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.website.url) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.website.url%22%5D)",
"command.frontMatter.settings.refresh": "Refresh Front Matter Settings",
"setting.frontMatter.config.dynamicFilePath.markdownDescription": "Specify the path to the dynamic config file (ex: [[workspace]]/config.js). [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.config.dynamicfilepath)",
"setting.frontMatter.config.dynamicFilePath.markdownDescription": "Specify the path to the dynamic config file (ex: [[workspace]]/config.js). [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.config.dynamicfilepath) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.config.dynamicfilepath%22%5D)",
"setting.frontMatter.taxonomy.contentTypes.items.properties.allowAsSubContent.description": "Specify if the content type can be used as sub content.",
"setting.frontMatter.taxonomy.contentTypes.items.properties.isSubContent.description": "Specify if the content type is sub content.",
"setting.frontMatter.git.disableOnBranches.markdownDescription": "Specify the branches on which you want to disable the Git actions. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.disableonbranches)",
"setting.frontMatter.git.requiresCommitMessage.markdownDescription": "Specify if you want to require a commit message when publishing your changes for a specified branch. [Check in the docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.requirescommitmessage)"
}
"setting.frontMatter.git.disableOnBranches.markdownDescription": "Specify the branches on which you want to disable the Git actions. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.disableonbranches) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.disableonbranches%22%5D)",
"setting.frontMatter.git.requiresCommitMessage.markdownDescription": "Specify if you want to require a commit message when publishing your changes for a specified branch. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.git.requirescommitmessage) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.git.requirescommitmessage%22%5D)",
"setting.frontMatter.copilot.family.markdownDescription": "Specify the LLM family of the Copilot you want to use. [Docs](https://frontmatter.codes/docs/settings/overview#frontmatter.copilot.family) - [View in VS Code](command:simpleBrowser.show?%5B%22https://frontmatter.codes/docs/settings/overview%23frontmatter.copilot.family%22%5D)"
}

View File

@@ -5,13 +5,15 @@ const core = require('@actions/core');
const packageJson = require('../package.json');
const version = packageJson.version.split('.');
packageJson.version = `${version[0]}.${version[1]}.${process.argv[process.argv.length-1].substr(0, 7)}`;
packageJson.version = `${version[0]}.${version[1]}.${process.argv[
process.argv.length - 1
].substring(0, 9)}`;
packageJson.preview = true;
packageJson.name = "vscode-front-matter-beta";
packageJson.name = 'vscode-front-matter-beta';
packageJson.displayName = `${packageJson.displayName} (BETA)`;
packageJson.description = `BETA Version of Front Matter. ${packageJson.description}`;
packageJson.icon = "assets/frontmatter-beta.png";
packageJson.homepage = "https://beta.frontmatter.codes";
packageJson.icon = 'assets/frontmatter-beta.png';
packageJson.homepage = 'https://beta.frontmatter.codes';
console.log(packageJson.version);
@@ -20,19 +22,24 @@ core.summary.addHeading(`Version info`).addRaw(`Version: ${packageJson.version}`
const scripts = packageJson.scripts;
for (const key in scripts) {
if (key.startsWith(`prod:`)) {
scripts[key] = scripts[key].replace("production", "development");
scripts[key] = scripts[key].replace('production', 'development');
}
}
console.log(JSON.stringify(packageJson.scripts, null, 2));
fs.writeFileSync(path.join(path.resolve('.'), 'package.json'), JSON.stringify(packageJson, null, 2));
fs.writeFileSync(
path.join(path.resolve('.'), 'package.json'),
JSON.stringify(packageJson, null, 2)
);
let readme = fs.readFileSync(path.join(__dirname, '../README.beta.md'), 'utf8');
fs.writeFileSync(path.join(__dirname, '../README.md'), readme);
// Update the .vscodeignore file
const ignoreFilePath = path.join(path.resolve('.'), '.vscodeignore');
let vscodeignore = fs.readFileSync(ignoreFilePath, 'utf8');
vscodeignore = vscodeignore.replace(`**/*.map`, '');
fs.writeFileSync(ignoreFilePath, vscodeignore);
if (fs.existsSync(ignoreFilePath)) {
let vscodeignore = fs.readFileSync(ignoreFilePath, 'utf8');
vscodeignore = vscodeignore.replace(`**/*.map`, '');
fs.writeFileSync(ignoreFilePath, vscodeignore);
}

View File

@@ -20,13 +20,12 @@ import {
SETTING_SLUG_PREFIX,
SETTING_SLUG_SUFFIX,
SETTING_CONTENT_PLACEHOLDERS,
TelemetryEvent,
SETTING_SLUG_TEMPLATE
} from './../constants';
import { CustomPlaceholder, Field } from '../models';
import { format } from 'date-fns';
import {
ArticleHelper,
Logger,
Settings,
SlugHelper,
processArticlePlaceholdersFromData,
@@ -38,13 +37,13 @@ import { COMMAND_NAME, DefaultFields } from '../constants';
import { DashboardData, SnippetInfo, SnippetRange } from '../models/DashboardData';
import { DateHelper } from '../helpers/DateHelper';
import { parseWinPath } from '../helpers/parseWinPath';
import { Telemetry } from '../helpers/Telemetry';
import { ParsedFrontMatter } from '../parsers';
import { MediaListener } from '../listeners/panel';
import { NavigationType } from '../dashboardWebView/models';
import { SNIPPET } from '../constants/Snippet';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { formatInTimezone, getTitleField } from '../utils';
export class Article {
/**
@@ -52,7 +51,7 @@ export class Article {
*
* @param subscriptions - The array of subscriptions to register the commands with.
*/
public static async registerCommands(subscriptions: unknown[]) {
public static registerCommands(subscriptions: unknown[]) {
subscriptions.push(
commands.registerCommand(COMMAND_NAME.setLastModifiedDate, Article.setLastModifiedDate)
);
@@ -66,6 +65,15 @@ export class Article {
subscriptions.push(commands.registerCommand(COMMAND_NAME.insertSnippet, Article.insertSnippet));
}
/**
* Registers event listeners for the Article class.
*
* @param subscriptions - An array to which the event listener will be added.
*/
public static registerListeners(subscriptions: unknown[]) {
subscriptions.push(workspace.onWillSaveTextDocument(Article.autoUpdate));
}
/**
* Sets the article date
*/
@@ -133,6 +141,7 @@ export class Article {
private static async setLastModifiedDateInner(
document: TextDocument
): Promise<ParsedFrontMatter | undefined> {
Logger.verbose(`Article:setLastModifiedDateInner:Start`);
const article = ArticleHelper.getFrontMatterFromDocument(document);
// Only set the date, if there is already front matter set
@@ -142,9 +151,16 @@ export class Article {
const cloneArticle = Object.assign({}, article);
const dateField = await ArticleHelper.getModifiedDateField(article);
Logger.verbose(`Article:setLastModifiedDateInner:DateField - ${JSON.stringify(dateField)}`);
try {
const fieldName = dateField?.name || DefaultFields.LastModified;
cloneArticle.data[fieldName] = Article.formatDate(new Date(), dateField?.dateFormat);
const fieldValue = Article.formatDate(new Date(), dateField?.dateFormat);
cloneArticle.data[fieldName] = fieldValue;
Logger.verbose(
`Article:setLastModifiedDateInner:DateField name - ${fieldName} - value - ${fieldValue}`
);
Logger.verbose(`Article:setLastModifiedDateInner:End`);
return cloneArticle;
} catch (e: unknown) {
Notifications.error(
@@ -156,7 +172,12 @@ export class Article {
/**
* Generate the new slug
*/
public static generateSlug(title: string, article?: ParsedFrontMatter, slugTemplate?: string) {
public static generateSlug(
title: string,
article?: ParsedFrontMatter,
filePath?: string,
slugTemplate?: string
) {
if (!title) {
return;
}
@@ -165,9 +186,9 @@ export class Article {
const suffix = Settings.get(SETTING_SLUG_SUFFIX) as string;
if (article?.data) {
const slug = SlugHelper.createSlug(title, article?.data, slugTemplate);
const slug = SlugHelper.createSlug(title, article?.data, filePath, slugTemplate);
if (slug) {
if (typeof slug === 'string') {
return {
slug,
slugWithPrefixAndSuffix: `${prefix}${slug}${suffix}`
@@ -182,8 +203,6 @@ export class Article {
* Generate the slug based on the article title
*/
public static async updateSlug() {
Telemetry.send(TelemetryEvent.generateSlug);
const updateFileName = Settings.get(SETTING_SLUG_UPDATE_FILE_NAME) as string;
const editor = window.activeTextEditor;
@@ -196,19 +215,32 @@ export class Article {
return;
}
const titleField = getTitleField();
const articleTitle: string = article.data[titleField];
const articleDate = await ArticleHelper.getDate(article);
let filePrefix = Settings.get<string>(SETTING_TEMPLATES_PREFIX);
const contentType = await ArticleHelper.getContentType(article);
filePrefix = await ArticleHelper.getFilePrefix(
filePrefix,
editor.document.uri.fsPath,
contentType
contentType,
articleTitle,
articleDate
);
const titleField = 'title';
const articleTitle: string = article.data[titleField];
const slugInfo = Article.generateSlug(articleTitle, article, contentType.slugTemplate);
const slugInfo = Article.generateSlug(
articleTitle,
article,
editor.document.uri.fsPath,
contentType.slugTemplate
);
if (slugInfo && slugInfo.slug && slugInfo.slugWithPrefixAndSuffix) {
if (
slugInfo &&
typeof slugInfo.slug === 'string' &&
typeof slugInfo.slugWithPrefixAndSuffix === 'string'
) {
article.data['slug'] = slugInfo.slugWithPrefixAndSuffix;
if (contentType) {
@@ -233,7 +265,8 @@ export class Article {
article.data[pField.name] = processArticlePlaceholdersFromData(
article.data[pField.name],
article.data,
contentType
contentType,
editor.document.uri.fsPath
);
article.data[pField.name] = processTimePlaceholders(
article.data[pField.name],
@@ -258,7 +291,11 @@ export class Article {
let newFileName = `${slugName}${ext}`;
if (filePrefix && typeof filePrefix === 'string') {
newFileName = `${filePrefix}-${newFileName}`;
if (filePrefix.endsWith('/')) {
newFileName = `${filePrefix}${newFileName}`;
} else {
newFileName = `${filePrefix}-${newFileName}`;
}
}
const newPath = editor.document.uri.fsPath.replace(fileName, newFileName);
@@ -285,7 +322,7 @@ export class Article {
/**
* Retrieve the slug from the front matter
*/
public static getSlug() {
public static getSlug(pathname?: string) {
const editor = window.activeTextEditor;
if (!editor) {
return;
@@ -298,17 +335,18 @@ export class Article {
const parsedFile = parse(file);
const titleField = getTitleField();
const slugTemplate = Settings.get<string>(SETTING_SLUG_TEMPLATE);
if (slugTemplate) {
if (slugTemplate === '{{title}}') {
const article = ArticleHelper.getFrontMatter(editor);
if (article?.data?.title) {
return article.data.title.toLowerCase().replace(/\s/g, '-');
if (article?.data && article.data[titleField]) {
return article.data[titleField].toLowerCase().replace(/\s/g, '-');
}
} else {
const article = ArticleHelper.getFrontMatter(editor);
if (article?.data) {
return SlugHelper.createSlug(article.data.title, article.data, slugTemplate);
return SlugHelper.createSlug(article.data[titleField], article.data, file, slugTemplate);
}
}
}
@@ -320,6 +358,10 @@ export class Article {
return `${prefix}${parsedFile.name}${suffix}`;
}
if (parsedFile.name.toLowerCase() === 'index' && pathname) {
return ``;
}
const folderName = basename(dirname(file));
return folderName;
}
@@ -346,7 +388,7 @@ export class Article {
* Article auto updater
* @param event
*/
public static async autoUpdate(event: TextDocumentWillSaveEvent) {
public static autoUpdate(event: TextDocumentWillSaveEvent) {
const document = event.document;
if (document && ArticleHelper.isSupportedFile(document)) {
const autoUpdate = Settings.get(SETTING_AUTO_UPDATE_DATE);
@@ -354,7 +396,7 @@ export class Article {
// Is article located in one of the content folders
const folders = Folders.getCached();
const documentPath = parseWinPath(document.fileName);
const folder = folders.find((f) => documentPath.startsWith(f.path));
const folder = folders?.find((f) => documentPath.startsWith(f.path));
if (!folder) {
return;
}
@@ -371,11 +413,16 @@ export class Article {
public static formatDate(dateValue: Date, fieldDateFormat?: string): string {
const dateFormat = Settings.get(SETTING_DATE_FORMAT) as string;
Logger.verbose(`Article:formatDate:Start`);
if (fieldDateFormat) {
return format(dateValue, DateHelper.formatUpdate(fieldDateFormat) as string);
Logger.verbose(`Article:formatDate:FieldDateFormat - ${fieldDateFormat}`);
return formatInTimezone(dateValue, DateHelper.formatUpdate(fieldDateFormat) as string);
} else if (dateFormat && typeof dateFormat === 'string') {
return format(dateValue, DateHelper.formatUpdate(dateFormat) as string);
Logger.verbose(`Article:formatDate:DateFormat - ${dateFormat}`);
return formatInTimezone(dateValue, DateHelper.formatUpdate(dateFormat) as string);
} else {
Logger.verbose(`Article:formatDate:toISOString - ${dateValue}`);
return typeof dateValue.toISOString === 'function'
? dateValue.toISOString()
: dateValue?.toString();
@@ -472,11 +519,12 @@ export class Article {
const article = ArticleHelper.getFrontMatter(editor);
const contentType = article ? await ArticleHelper.getContentType(article) : undefined;
const tileField = getTitleField();
await commands.executeCommand(COMMAND_NAME.dashboard, {
type: NavigationType.Snippets,
data: {
fileTitle: article?.data.title || '',
fileTitle: article?.data[tileField] || '',
filePath: editor.document.uri.fsPath,
fieldName: basename(editor.document.uri.fsPath),
contentType,

View File

@@ -1,5 +1,5 @@
import { authentication, commands, ExtensionContext } from 'vscode';
import { COMMAND_NAME, CONTEXT } from '../constants';
import { COMMAND_NAME, CONTEXT, WEBSITE_LINKS } from '../constants';
import { Extension, Logger } from '../helpers';
import { Dashboard } from './Dashboard';
import { SettingsListener } from '../listeners/panel';
@@ -22,9 +22,8 @@ export class Backers {
const githubAuth = await authentication.getSession('github', ['read:user'], { silent: true });
if (githubAuth && githubAuth.accessToken) {
try {
const isBeta = ext.isBetaVersion();
const response = await fetch(
`https://${isBeta ? `beta.` : ``}frontmatter.codes/api/v2/backers`,
`${WEBSITE_LINKS.api.baseUrl}${WEBSITE_LINKS.api.endpoints.backers}`,
{
method: 'POST',
headers: {

View File

@@ -1,5 +1,4 @@
import { Telemetry } from './../helpers/Telemetry';
import { TelemetryEvent, PreviewCommands, GeneralCommands } from './../constants';
import { PreviewCommands, GeneralCommands } from './../constants';
import { join } from 'path';
import { commands, Uri, ViewColumn, window } from 'vscode';
import { Extension } from '../helpers';
@@ -7,6 +6,7 @@ import { WebviewHelper } from '@estruyf/vscode';
import { getLocalizationFile } from '../utils/getLocalizationFile';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { getWebviewJsFiles } from '../utils';
export class Chatbot {
/**
@@ -33,31 +33,36 @@ export class Chatbot {
const cspSource = webView.webview.cspSource;
const fetchLocalization = async (requestId: string) => {
if (!requestId) {
return;
}
const fileContents = await getLocalizationFile();
webView.webview.postMessage({
command: GeneralCommands.toVSCode.getLocalization,
requestId,
payload: fileContents
});
};
webView.webview.onDidReceiveMessage(async (message) => {
switch (message.command) {
const { command, requestId, payload, data } = message;
switch (command) {
case PreviewCommands.toVSCode.open:
if (message.data) {
commands.executeCommand('vscode.open', message.data);
if (payload || data) {
commands.executeCommand('vscode.open', payload || data);
}
return;
break;
case GeneralCommands.toVSCode.getLocalization:
const { requestId } = message;
if (!requestId) {
return;
}
const fileContents = await getLocalizationFile();
webView.webview.postMessage({
command: GeneralCommands.toVSCode.getLocalization,
requestId,
payload: fileContents
});
fetchLocalization(requestId);
return;
}
});
const dashboardFile = 'dashboardWebView.js';
const webviewFile = 'dashboard.main.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
@@ -67,7 +72,6 @@ export class Chatbot {
const isProd = ext.isProductionMode;
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
const extensionUri = ext.extensionPath;
const csp = [
`default-src 'none';`,
@@ -83,13 +87,11 @@ export class Chatbot {
}`
];
let scriptUri = '';
let scriptUris = [];
if (isProd) {
scriptUri = webView.webview
.asWebviewUri(Uri.joinPath(extensionUri, 'dist', dashboardFile))
.toString();
scriptUris = await getWebviewJsFiles('dashboard', webView.webview);
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUris.push(`http://${localServerUrl}/${webviewFile}`);
}
// By default, the chatbot is seen as experimental
@@ -112,11 +114,13 @@ export class Chatbot {
experimental ? `data-experimental="${experimental}"` : ''
} style="width:100%;height:100%;margin:0;padding:0;"></div>
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
${scriptUris
.map((uri) => `<script ${isProd ? `nonce="${nonce}"` : ''} src="${uri}"></script>`)
.join('\n')}
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759&slug=${`chatbot-${version.installedVersion}`}" alt="Daily usage" />
</body>
</html>
`;
Telemetry.send(TelemetryEvent.openChatbot);
}
}

View File

@@ -3,9 +3,7 @@ import {
CONTEXT,
ExtensionState,
SETTING_EXPERIMENTAL,
SETTING_EXTENSIBILITY_SCRIPTS,
COMMAND_NAME,
TelemetryEvent
COMMAND_NAME
} from '../constants';
import { join } from 'path';
import { commands, Uri, ViewColumn, Webview, WebviewPanel, window } from 'vscode';
@@ -18,7 +16,6 @@ import {
DashboardListener,
MediaListener,
SettingsListener,
TelemetryListener,
DataListener,
PagesListener,
ExtensionListener,
@@ -29,12 +26,11 @@ import {
} from '../listeners/dashboard';
import { MediaListener as PanelMediaListener } from '../listeners/panel';
import { GitListener, ModeListener } from '../listeners/general';
import { Folders } from './Folders';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { DashboardMessage } from '../dashboardWebView/DashboardMessage';
import { NavigationType } from '../dashboardWebView/models';
import { ignoreMsgCommand } from '../utils';
import { getExtensibilityScripts, getWebviewJsFiles, ignoreMsgCommand } from '../utils';
export class Dashboard {
private static webview: WebviewPanel | null = null;
@@ -67,7 +63,6 @@ export class Dashboard {
subscriptions.push(
commands.registerCommand(COMMAND_NAME.dashboard, (data?: DashboardData) => {
Telemetry.send(TelemetryEvent.openContentDashboard);
if (!data) {
Dashboard.open({ type: NavigationType.Contents });
} else {
@@ -78,35 +73,30 @@ export class Dashboard {
subscriptions.push(
commands.registerCommand(COMMAND_NAME.dashboardMedia, () => {
Telemetry.send(TelemetryEvent.openMediaDashboard);
Dashboard.open({ type: NavigationType.Media });
})
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.dashboardSnippets, () => {
Telemetry.send(TelemetryEvent.openSnippetsDashboard);
Dashboard.open({ type: NavigationType.Snippets });
})
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.dashboardData, () => {
Telemetry.send(TelemetryEvent.openDataDashboard);
Dashboard.open({ type: NavigationType.Data });
})
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.dashboardTaxonomy, () => {
Telemetry.send(TelemetryEvent.openTaxonomyDashboard);
Dashboard.open({ type: NavigationType.Taxonomy });
})
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.dashboardClose, () => {
Telemetry.send(TelemetryEvent.closeDashboard);
Dashboard.close();
})
);
@@ -241,7 +231,6 @@ export class Dashboard {
PagesListener.process(msg);
SettingsListener.process(msg);
DataListener.process(msg);
TelemetryListener.process(msg);
SnippetListener.process(msg);
ModeListener.process(msg);
GitListener.process(msg);
@@ -285,18 +274,17 @@ export class Dashboard {
* @param webView
*/
private static async getWebviewContent(webView: Webview, extensionPath: Uri): Promise<string> {
const dashboardFile = 'dashboardWebView.js';
const webviewFile = 'dashboard.main.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
let scriptUri = '';
const isProd = Extension.getInstance().isProductionMode;
let scriptUris = [];
if (isProd) {
scriptUri = webView
.asWebviewUri(Uri.joinPath(extensionPath, 'dist', dashboardFile))
.toString();
scriptUris = await getWebviewJsFiles('dashboard', webView);
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUris.push(`http://${localServerUrl}/${webviewFile}`);
}
const nonce = WebviewHelper.getNonce();
@@ -307,20 +295,8 @@ export class Dashboard {
// Get experimental setting
const experimental = SettingsHelper.get(SETTING_EXPERIMENTAL);
const extensibilityScripts = SettingsHelper.get<string[]>(SETTING_EXTENSIBILITY_SCRIPTS) || [];
const scriptsToLoad: string[] = [];
if (experimental) {
for (const script of extensibilityScripts) {
if (script.startsWith('https://')) {
scriptsToLoad.push(script);
} else {
const absScriptPath = Folders.getAbsFilePath(script);
const scriptUri = webView.asWebviewUri(Uri.file(absScriptPath));
scriptsToLoad.push(scriptUri.toString());
}
}
}
const scriptsToLoad: string[] = getExtensibilityScripts(webView);
const csp = [
`default-src 'none';`,
@@ -374,7 +350,9 @@ export class Dashboard {
})
.join('')}
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
${scriptUris
.map((uri) => `<script ${isProd ? `nonce="${nonce}"` : ''} src="${uri}"></script>`)
.join('\n')}
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759&slug=${`dashboard-${version.installedVersion}`}" alt="Daily usage" />
</body>

View File

@@ -1,5 +1,5 @@
import { Folders } from './Folders';
import { ViewColumn, commands, workspace } from 'vscode';
import { ViewColumn, commands, version, workspace } from 'vscode';
import ContentProvider from '../providers/ContentProvider';
import { join } from 'path';
import { ContentFolder } from '../models';
@@ -37,6 +37,8 @@ export class Diagnostics {
Beta: \`${Extension.getInstance().isBetaVersion()}\`
Version: \`${Extension.getInstance().version}\`
OS: \`${process.platform}\`
VSCode version: \`${version}\`
## Project name

View File

@@ -6,34 +6,39 @@ import {
SETTING_CONTENT_PAGE_FOLDERS,
SETTING_CONTENT_STATIC_FOLDER,
SETTING_CONTENT_SUPPORTED_FILETYPES,
SETTING_DATE_FORMAT,
TelemetryEvent
SETTING_DATE_FORMAT
} from './../constants';
import { commands, Uri, workspace, window } from 'vscode';
import { basename, dirname, join, relative, sep } from 'path';
import { ContentFolder, FileInfo, FolderInfo, I18nConfig, StaticFolder } from '../models';
import {
ContentFolder,
ContentType,
FileInfo,
FolderInfo,
I18nConfig,
StaticFolder
} from '../models';
import uniqBy = require('lodash.uniqby');
import { Template } from './Template';
import { Notifications } from '../helpers/Notifications';
import { Extension, Logger, Settings, processTimePlaceholders } from '../helpers';
import { existsSync } from 'fs';
import { format } from 'date-fns';
import { Dashboard } from './Dashboard';
import { parseWinPath } from '../helpers/parseWinPath';
import { MediaHelpers } from '../helpers/MediaHelpers';
import { MediaListener, PagesListener, SettingsListener } from '../listeners/dashboard';
import { DEFAULT_FILE_TYPES } from '../constants/DefaultFileTypes';
import { Telemetry } from '../helpers/Telemetry';
import { glob } from 'glob';
import { mkdirAsync } from '../utils/mkdirAsync';
import { existsAsync, isWindows } from '../utils';
import { existsAsync, formatInTimezone, isWindows, lstatAsync } from '../utils';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { Preview } from './Preview';
export const WORKSPACE_PLACEHOLDER = `[[workspace]]`;
export class Folders {
private static _folders: ContentFolder[] = [];
private static _folders: ContentFolder[] | undefined = undefined;
public static async registerCommands() {
const ext = Extension.getInstance();
@@ -44,7 +49,7 @@ export class Folders {
public static clearCached() {
Logger.verbose(`Folders:clearCached`);
Folders._folders = [];
Folders._folders = undefined;
}
/**
@@ -79,7 +84,7 @@ export class Folders {
prompt: l10n.t(LocalizationKey.commandsFoldersAddMediaFolderInputBoxPrompt),
value: startPath,
ignoreFocusOut: true,
placeHolder: `${format(new Date(), `yyyy/MM`)}`
placeHolder: `${formatInTimezone(new Date(), `yyyy/MM`)}`
});
if (!folderName) {
@@ -99,8 +104,6 @@ export class Folders {
MediaHelpers.resetMedia();
MediaListener.sendMediaFiles(0, folderPath);
}
Telemetry.send(TelemetryEvent.addMediaFolder);
}
/**
@@ -175,8 +178,6 @@ export class Folders {
Notifications.info(l10n.t(LocalizationKey.commandsFoldersCreateSuccess));
Telemetry.send(TelemetryEvent.registerFolder);
SettingsListener.getSettings(true);
}
}
@@ -190,8 +191,6 @@ export class Folders {
let folders = await Folders.get();
folders = folders.filter((f) => f.path !== folder.fsPath);
await Folders.update(folders);
Telemetry.send(TelemetryEvent.unregisterFolder);
}
}
@@ -220,7 +219,9 @@ export class Folders {
: Folders.getAbsFilePath(assetFolder);
const wsFolder = Folders.getWorkspaceFolder();
if (wsFolder) {
const relativePath = relative(parseWinPath(wsFolder.fsPath), parseWinPath(assetFolder));
const relativePath = parseWinPath(
relative(parseWinPath(wsFolder.fsPath), parseWinPath(assetFolder))
);
return relativePath === '' ? '/' : relativePath;
}
}
@@ -327,7 +328,7 @@ export class Folders {
public static async get(): Promise<ContentFolder[]> {
Logger.verbose('Folders:get:start');
if (Folders._folders.length > 0) {
if (Folders._folders && Folders._folders.length > 0) {
Logger.verbose('Folders:get:end - cached folders');
return Folders._folders;
}
@@ -401,8 +402,8 @@ export class Folders {
folder.locales && folder.locales.length > 0 ? folder.locales : i18nSettings;
let defaultLocale;
let sourcePath = folderPath;
let localeFolders: ContentFolder[] = [];
const sourcePath = folderPath;
const localeFolders: ContentFolder[] = [];
if (i18nConfig && i18nConfig.length > 0) {
for (const i18n of i18nConfig) {
@@ -452,10 +453,23 @@ export class Folders {
* Get the cached folder settings
* @returns {ContentFolder[]} - The cached folder settings
*/
public static getCached(): ContentFolder[] {
public static getCached(): ContentFolder[] | undefined {
return Folders._folders;
}
/**
* Retrieves the cached content folders if available, otherwise fetches fresh content folders.
*
* @returns {Promise<ContentFolder[]>} A promise that resolves to an array of content folders.
*/
public static async getCachedOrFresh(): Promise<ContentFolder[]> {
if (Folders._folders && Folders._folders.length > 0) {
return Folders._folders;
}
return await Folders.get();
}
/**
* Update the folder settings
* @param folders
@@ -557,6 +571,22 @@ export class Folders {
return parseWinPath(absPath);
}
/**
* Converts a given file path to a workspace-relative path.
*
* @param path - The file path to convert.
* @returns The workspace-relative path.
*/
public static wsPath(path: string) {
const wsFolder = Folders.getWorkspaceFolder();
let absPath = parseWinPath(path).replace(
parseWinPath(wsFolder?.fsPath || ''),
WORKSPACE_PLACEHOLDER
);
absPath = isWindows() ? absPath.split('\\').join('/') : absPath;
return absPath;
}
/**
* Generate relative folder path
* @param folder
@@ -608,15 +638,23 @@ export class Folders {
}
}
// For Windows, we need to make sure the drive letter is lowercased for consistency
if (isWindows()) {
folders = folders.map((folder) => parseWinPath(folder));
}
// Filter out the workspace folder
if (wsFolder) {
folders = folders.filter((folder) => folder !== wsFolder.fsPath);
folders = folders.filter((folder) => folder !== parseWinPath(wsFolder.fsPath));
}
const uniqueFolders = [...new Set(folders)];
const relativeFolderPaths = uniqueFolders.map((folder) =>
parseWinPath(relative(parseWinPath(wsFolder.fsPath), folder))
);
Logger.verbose('Folders:getContentFolders:end');
return uniqueFolders.map((folder) => relative(wsFolder?.path || '', folder));
return relativeFolderPaths;
}
/**
@@ -640,7 +678,7 @@ export class Folders {
* @param filePath
* @returns
*/
public static async getFilePrefixBeFilePath(filePath: string) {
public static async getFilePrefixBeFilePath(filePath: string): Promise<string | undefined> {
const folders = await Folders.get();
if (folders.length > 0) {
filePath = parseWinPath(filePath);
@@ -672,7 +710,7 @@ export class Folders {
public static async getPageFolderByFilePath(
filePath: string
): Promise<ContentFolder | undefined> {
const folders = await Folders.get();
const folders = await Folders.getCachedOrFresh();
const parsedPath = parseWinPath(filePath);
const pageFolderMatches = folders
.filter((folder) => parsedPath && folder.path && parsedPath.includes(folder.path))
@@ -685,6 +723,49 @@ export class Folders {
return;
}
/**
* Retrieves the folder associated with the specified content type and file path.
* If a single matching folder is found, it is returned. If multiple matching folders are found,
* the user is prompted to select one. If no matching folders are found, the user is prompted to
* select a folder with a preview path.
*
* @param contentType - The content type to match.
* @param filePath - The file path to match.
* @returns A Promise that resolves to the selected ContentFolder, or undefined if no matching folder is found.
*/
public static async getFolderByContentType(
contentType: ContentType,
filePath: string
): Promise<ContentFolder | undefined> {
if (!contentType) {
return;
}
const folders = await Folders.getCachedOrFresh();
let selectedFolder: ContentFolder | undefined;
// Try to find the folder by content type
let crntFolders = folders.filter(
(folder) =>
folder.contentTypes?.includes((contentType as ContentType).name) && folder.previewPath
);
// Use file path to find the folder
if (crntFolders.length > 0) {
crntFolders = crntFolders.filter((folder) => filePath?.startsWith(folder.path));
}
if (crntFolders && crntFolders.length === 1) {
selectedFolder = crntFolders[0];
} else if (crntFolders && crntFolders.length > 1) {
selectedFolder = await Preview.askUserToPickFolder(crntFolders);
} else {
selectedFolder = await Preview.askUserToPickFolder(folders.filter((f) => f.previewPath));
}
return selectedFolder;
}
/**
* Retrieves the file stats for a given file.
* @param file - The URI of the file.
@@ -729,7 +810,11 @@ export class Folders {
filePath = `*${fileType.startsWith('.') ? '' : '.'}${fileType}`;
}
let foundFiles = await Folders.findFiles(filePath);
let foundFiles = await Folders.findFiles(
filePath,
join(folderPath, folder.excludeSubdir ? '/' : '**'),
folder.excludePaths
);
// Make sure these file are coming from the folder path (this could be an issue in multi-root workspaces)
foundFiles = foundFiles.filter((f) =>
@@ -784,9 +869,26 @@ export class Folders {
try {
pattern = isWindows() ? parseWinPath(pattern) : pattern;
const files = await glob(pattern, { ignore: '**/node_modules/**', dot: true });
const allFolders = (files || []).map((file) => dirname(file));
const uniqueFolders = [...new Set(allFolders)];
const folders = await glob(pattern, {
ignore: '**/node_modules/**',
dot: true
});
const onlyFolders = [];
for (const folder of folders) {
try {
const stats = await lstatAsync(folder);
if (stats.isDirectory()) {
onlyFolders.push(folder);
} else {
onlyFolders.push(dirname(folder));
}
} catch (e) {
continue;
}
}
const uniqueFolders = [...new Set(onlyFolders)];
Logger.verbose(`Folders:findFolders:end - ${uniqueFolders.length}`);
return uniqueFolders;
} catch (e) {
@@ -800,12 +902,27 @@ export class Folders {
* @param pattern
* @returns
*/
private static async findFiles(pattern: string): Promise<Uri[]> {
private static async findFiles(
pattern: string,
folderPath: string,
excludePaths: string[] = []
): Promise<Uri[]> {
Logger.verbose(`Folders:findFiles:start - ${pattern}`);
try {
pattern = isWindows() ? parseWinPath(pattern) : pattern;
const files = await glob(pattern, { ignore: '**/node_modules/**', dot: true });
const files = await glob(pattern, {
ignore: [
'**/node_modules/**',
...excludePaths.map((path) => {
// path can be a folder name or a wildcard.
// If its a folder name, we need to add a wildcard to the end
path = path.includes('*') ? path : join(path, '**');
return parseWinPath(join(folderPath, path));
})
],
dot: true
});
const allFiles = (files || []).map((file) => Uri.file(file));
Logger.verbose(`Folders:findFiles:end - ${allFiles.length}`);
return allFiles;

View File

@@ -2,7 +2,6 @@ import {
SETTING_PREVIEW_HOST,
SETTING_PREVIEW_PATHNAME,
CONTEXT,
TelemetryEvent,
PreviewCommands,
SETTING_EXPERIMENTAL,
SETTING_DATE_FORMAT,
@@ -20,7 +19,6 @@ import {
processFmPlaceholders,
processPathPlaceholders,
Settings,
Telemetry,
processDateTimePlaceholders
} from '../helpers';
import { ContentFolder, ContentType, PreviewSettings } from '../models';
@@ -31,7 +29,7 @@ import { ParsedFrontMatter } from '../parsers';
import { getLocalizationFile } from '../utils/getLocalizationFile';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { joinUrl } from '../utils';
import { getTitleField, getWebviewJsFiles, joinUrl } from '../utils';
import { i18n } from './i18n';
export class Preview {
@@ -77,11 +75,13 @@ export class Preview {
return;
}
const titleField = getTitleField();
// Create the preview webview
const webView = window.createWebviewPanel(
'frontMatterPreview',
article?.data?.title
? l10n.t(LocalizationKey.commandsPreviewPanelTitle, article?.data.title)
article?.data && article?.data[titleField]
? l10n.t(LocalizationKey.commandsPreviewPanelTitle, article?.data[titleField])
: 'Front Matter Preview',
{
viewColumn: ViewColumn.Beside,
@@ -110,31 +110,36 @@ export class Preview {
webView.dispose();
});
const fetchLocalization = async (requestId: string) => {
if (!requestId) {
return;
}
const fileContents = await getLocalizationFile();
webView.webview.postMessage({
command: GeneralCommands.toVSCode.getLocalization,
requestId,
payload: fileContents
});
};
webView.webview.onDidReceiveMessage(async (message) => {
switch (message.command) {
const { command, payload, requestId } = message;
switch (command) {
case PreviewCommands.toVSCode.open:
if (message.payload) {
commands.executeCommand('vscode.open', message.payload);
if (payload) {
commands.executeCommand('vscode.open', payload);
}
return;
break;
case GeneralCommands.toVSCode.getLocalization:
const { requestId } = message;
if (!requestId) {
return;
}
const fileContents = await getLocalizationFile();
webView.webview.postMessage({
command: GeneralCommands.toVSCode.getLocalization,
requestId,
payload: fileContents
});
return;
fetchLocalization(requestId);
break;
}
});
const dashboardFile = 'dashboardWebView.js';
const webviewFile = 'dashboard.main.js';
const localPort = `9000`;
const localServerUrl = `localhost:${localPort}`;
@@ -144,7 +149,6 @@ export class Preview {
const isProd = ext.isProductionMode;
const version = ext.getVersion();
const isBeta = ext.isBetaVersion();
const extensionUri = ext.extensionPath;
const csp = [
`default-src 'none';`,
@@ -161,13 +165,11 @@ export class Preview {
`frame-src ${localhostUrl} ${cspSource} http: https:;`
];
let scriptUri = '';
let scriptUris = [];
if (isProd) {
scriptUri = webView.webview
.asWebviewUri(Uri.joinPath(extensionUri, 'dist', dashboardFile))
.toString();
scriptUris = await getWebviewJsFiles('dashboard', webView.webview);
} else {
scriptUri = `http://${localServerUrl}/${dashboardFile}`;
scriptUris.push(`http://${localServerUrl}/${webviewFile}`);
}
// Get experimental setting
@@ -193,12 +195,14 @@ export class Preview {
experimental ? `data-experimental="${experimental}"` : ''
} style="width:100%;height:100%;margin:0;padding:0;"></div>
<script ${isProd ? `nonce="${nonce}"` : ''} src="${scriptUri}"></script>
${scriptUris
.map((uri) => `<script ${isProd ? `nonce="${nonce}"` : ''} src="${uri}"></script>`)
.join('\n')}
<img style="display:none" src="https://api.visitorbadge.io/api/combined?user=estruyf&repo=frontmatter-usage&countColor=%23263759&slug=${`preview-${version.installedVersion}`}" alt="Daily usage" />
</body>
</html>
`;
Telemetry.send(TelemetryEvent.openPreview);
}
/**
@@ -247,44 +251,15 @@ export class Preview {
contentType = await ArticleHelper.getContentType(article);
}
// Check if there is a pathname defined on content folder level
const folders = await Folders.get();
if (folders.length > 0) {
const foldersWithPath = folders.filter((folder) => folder.previewPath);
// Get the folder of the article by the file path
selectedFolder = await Folders.getPageFolderByFilePath(filePath);
for (const folder of foldersWithPath) {
const folderPath = parseWinPath(folder.path);
if (filePath.startsWith(folderPath)) {
if (!selectedFolder || selectedFolder.path.length < folderPath.length) {
selectedFolder = folder;
}
}
}
if (!selectedFolder && contentType) {
selectedFolder = await Folders.getFolderByContentType(contentType, filePath);
}
if (!selectedFolder && article?.data && contentType && !contentType.previewPath) {
// Try to find the folder by content type
let crntFolders = folders.filter(
(folder) =>
folder.contentTypes?.includes((contentType as ContentType).name) && folder.previewPath
);
// Use file path to find the folder
if (crntFolders.length > 0) {
crntFolders = crntFolders.filter((folder) => filePath?.startsWith(folder.path));
}
if (crntFolders && crntFolders.length === 1) {
selectedFolder = crntFolders[0];
} else if (crntFolders && crntFolders.length > 1) {
selectedFolder = await Preview.askUserToPickFolder(crntFolders);
} else {
selectedFolder = await Preview.askUserToPickFolder(folders.filter((f) => f.previewPath));
}
}
if (selectedFolder && selectedFolder.previewPath) {
pathname = selectedFolder.previewPath;
}
if (selectedFolder && selectedFolder.previewPath) {
pathname = selectedFolder.previewPath;
}
// Check if there is a pathname defined on content type level
@@ -295,7 +270,7 @@ export class Preview {
}
if (!slug) {
slug = Article.getSlug();
slug = Article.getSlug(pathname);
}
const locale = await i18n.getLocale(filePath);
@@ -341,7 +316,7 @@ export class Preview {
try {
const articleDate = await ArticleHelper.getDate(article);
pathname = processDateTimePlaceholders(pathname, dateFormat, articleDate);
pathname = processDateTimePlaceholders(pathname, articleDate);
slug = join(pathname, slug);
} catch (error) {
slug = join(pathname, slug);
@@ -374,7 +349,7 @@ export class Preview {
slug = `${slug}/`;
}
return slug;
return join(slug);
}
/**
@@ -424,7 +399,7 @@ export class Preview {
* @param crntFolders
* @returns
*/
private static async askUserToPickFolder(
public static async askUserToPickFolder(
crntFolders: ContentFolder[]
): Promise<ContentFolder | undefined> {
let selectedFolder: ContentFolder | undefined = undefined;

View File

@@ -1,5 +1,4 @@
import { DEFAULT_CONTENT_TYPE } from './../constants/ContentType';
import { Telemetry } from './../helpers/Telemetry';
import { workspace, Uri, commands, window } from 'vscode';
import { join } from 'path';
import { Notifications } from '../helpers/Notifications';
@@ -16,8 +15,7 @@ import {
import {
COMMAND_NAME,
SETTING_CONTENT_DEFAULT_FILETYPE,
SETTING_TAXONOMY_CONTENT_TYPES,
TelemetryEvent
SETTING_TAXONOMY_CONTENT_TYPES
} from '../constants';
import { SettingsListener } from '../listeners/dashboard';
import { existsAsync, writeFileAsync } from '../utils';
@@ -44,7 +42,7 @@ categories: []
// Initialize command
subscriptions.push(
commands.registerCommand(COMMAND_NAME.init, async (cb: Function) => {
commands.registerCommand(COMMAND_NAME.init, async (cb: () => void) => {
await Project.init();
if (cb) {
@@ -96,8 +94,6 @@ categories: []
// Initialize the taxonomy database
TaxonomyHelper.initDb();
Telemetry.send(TelemetryEvent.initialization);
// Check if you can find the framework
const wsFolder = Folders.getWorkspaceFolder();
const framework = await FrameworkDetector.get(wsFolder?.fsPath || '');

View File

@@ -3,15 +3,12 @@ import {
CONTEXT,
EXTENSION_NAME,
NOTIFICATION_TYPE,
SETTING_SEO_DESCRIPTION_FIELD,
SETTING_SEO_DESCRIPTION_LENGTH,
SETTING_SEO_TITLE_FIELD,
SETTING_SEO_TITLE_LENGTH
} from './../constants';
import * as vscode from 'vscode';
import { ArticleHelper, Notifications, SeoHelper, Settings } from '../helpers';
import { PanelProvider } from '../panelWebView/PanelProvider';
import { DefaultFields } from '../constants';
import { ContentType } from '../helpers/ContentType';
import { DataListener } from '../listeners/panel';
import { commands } from 'vscode';
@@ -20,6 +17,7 @@ import { Preview } from './Preview';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { i18n } from './i18n';
import { getDescriptionField, getTitleField } from '../utils';
export class StatusListener {
/**
@@ -56,12 +54,10 @@ export class StatusListener {
collection.clear();
// Retrieve the SEO config properties
const titleLength = (Settings.get(SETTING_SEO_TITLE_LENGTH) as number) || -1;
const descLength = (Settings.get(SETTING_SEO_DESCRIPTION_LENGTH) as number) || -1;
const titleField =
(Settings.get(SETTING_SEO_TITLE_FIELD) as string) || DefaultFields.Title;
const descriptionField =
(Settings.get(SETTING_SEO_DESCRIPTION_FIELD) as string) || DefaultFields.Description;
const titleLength = Settings.get<number>(SETTING_SEO_TITLE_LENGTH) || -1;
const descLength = Settings.get<number>(SETTING_SEO_DESCRIPTION_LENGTH) || -1;
const titleField = getTitleField();
const descriptionField = getDescriptionField();
if (editor && article.data[titleField] && titleLength > -1) {
SeoHelper.checkLength(editor, collection, article, titleField, titleLength);

33
src/commands/Taxonomy.ts Normal file
View File

@@ -0,0 +1,33 @@
import { commands } from 'vscode';
import { COMMAND_NAME } from '../constants';
import { TagType } from '../panelWebView/TagType';
import { PanelProvider } from '../panelWebView/PanelProvider';
export class Taxonomy {
/**
* Registers the commands for the Article class.
*
* @param subscriptions - The array of subscriptions to register the commands with.
*/
public static async registerCommands(subscriptions: unknown[]) {
const explorerSidebar = PanelProvider.getInstance();
if (explorerSidebar) {
subscriptions.push(
commands.registerCommand(COMMAND_NAME.insertTags, async () => {
await commands.executeCommand('workbench.view.extension.frontmatter-explorer');
await commands.executeCommand('workbench.action.focusSideBar');
explorerSidebar.triggerInputFocus(TagType.tags);
})
);
subscriptions.push(
commands.registerCommand(COMMAND_NAME.insertCategories, async () => {
await commands.executeCommand('workbench.view.extension.frontmatter-explorer');
await commands.executeCommand('workbench.action.focusSideBar');
explorerSidebar.triggerInputFocus(TagType.categories);
})
);
}
}
}

View File

@@ -3,9 +3,9 @@ import * as vscode from 'vscode';
import * as path from 'path';
import {
COMMAND_NAME,
DefaultFields,
SETTING_CONTENT_DEFAULT_FILETYPE,
SETTING_TEMPLATES_FOLDER,
TelemetryEvent
SETTING_TEMPLATES_FOLDER
} from '../constants';
import { ArticleHelper, Extension, Settings } from '../helpers';
import { Article, Folders } from '.';
@@ -15,7 +15,6 @@ import { ContentType } from '../helpers/ContentType';
import { ContentType as IContentType } from '../models';
import { PagesListener } from '../listeners/dashboard';
import { extname } from 'path';
import { Telemetry } from '../helpers/Telemetry';
import { writeFileAsync, copyFileAsync } from '../utils';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
@@ -163,8 +162,14 @@ export class Template {
const templateData = await ArticleHelper.getFrontMatterByPath(template.fsPath);
let contentType: IContentType | undefined;
if (templateData && templateData.data && templateData.data.type) {
contentType = contentTypes?.find((t) => t.name === templateData.data.type);
if (templateData && templateData.data) {
if (templateData.data[DefaultFields.ContentType]) {
contentType = contentTypes?.find(
(t) => t.name === templateData.data[DefaultFields.ContentType]
);
} else if (templateData.data[DefaultFields.Type]) {
contentType = contentTypes?.find((t) => t.name === templateData.data[DefaultFields.Type]);
}
}
const fileExtension = extname(template.fsPath).replace('.', '');
@@ -217,8 +222,6 @@ export class Template {
Notifications.info(l10n.t(LocalizationKey.commandsTemplateCreateSuccess));
Telemetry.send(TelemetryEvent.createContentFromTemplate);
// Trigger a refresh for the dashboard
PagesListener.refresh();
}

View File

@@ -1,8 +1,7 @@
import { commands, window, Selection, QuickPickItem, TextEditor } from 'vscode';
import { COMMAND_NAME, CONTEXT, SETTING_CONTENT_WYSIWYG } from '../constants';
import { Settings } from '../helpers';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { LocalizationKey, localize } from '../localization';
enum MarkupType {
bold = 1,
@@ -18,6 +17,8 @@ enum MarkupType {
hyperlink
}
type DocType = 'markdown' | 'asciidoc';
export class Wysiwyg {
/**
* Registers the markup commands for the WYSIWYG controls
@@ -83,45 +84,45 @@ export class Wysiwyg {
commands.registerCommand(COMMAND_NAME.options, async () => {
const qpItems: QuickPickItem[] = [
{
label: `$(list-unordered) ${LocalizationKey.commandsWysiwygCommandUnorderedListLabel}`,
detail: LocalizationKey.commandsWysiwygCommandUnorderedListDetail,
label: `$(list-unordered) ${localize(LocalizationKey.commandsWysiwygCommandUnorderedListLabel)}`,
detail: localize(LocalizationKey.commandsWysiwygCommandUnorderedListDetail),
alwaysShow: true
},
{
label: `$(list-ordered) ${LocalizationKey.commandsWysiwygCommandOrderedListLabel}`,
detail: LocalizationKey.commandsWysiwygCommandOrderedListDetail,
label: `$(list-ordered) ${localize(LocalizationKey.commandsWysiwygCommandOrderedListLabel)}`,
detail: localize(LocalizationKey.commandsWysiwygCommandOrderedListDetail),
alwaysShow: true
},
{
label: `$(tasklist) ${LocalizationKey.commandsWysiwygCommandTaskListLabel}`,
detail: LocalizationKey.commandsWysiwygCommandTaskListDetail,
label: `$(tasklist) ${localize(LocalizationKey.commandsWysiwygCommandTaskListLabel)}`,
detail: localize(LocalizationKey.commandsWysiwygCommandTaskListDetail),
alwaysShow: true
},
{
label: `$(code) ${LocalizationKey.commandsWysiwygCommandCodeLabel}`,
detail: LocalizationKey.commandsWysiwygCommandCodeDetail,
label: `$(code) ${localize(LocalizationKey.commandsWysiwygCommandCodeLabel)}`,
detail: localize(LocalizationKey.commandsWysiwygCommandCodeDetail),
alwaysShow: true
},
{
label: `$(symbol-namespace) ${LocalizationKey.commandsWysiwygCommandCodeblockLabel}`,
detail: LocalizationKey.commandsWysiwygCommandCodeblockDetail,
label: `$(symbol-namespace) ${localize(LocalizationKey.commandsWysiwygCommandCodeblockLabel)}`,
detail: localize(LocalizationKey.commandsWysiwygCommandCodeblockDetail),
alwaysShow: true
},
{
label: `$(quote) ${LocalizationKey.commandsWysiwygCommandBlockquoteLabel}`,
detail: LocalizationKey.commandsWysiwygCommandBlockquoteDetail,
label: `$(quote) ${localize(LocalizationKey.commandsWysiwygCommandBlockquoteLabel)}`,
detail: localize(LocalizationKey.commandsWysiwygCommandBlockquoteDetail),
alwaysShow: true
},
{
label: `$(symbol-text) ${LocalizationKey.commandsWysiwygCommandStrikethroughLabel}`,
detail: LocalizationKey.commandsWysiwygCommandStrikethroughDetail,
label: `$(symbol-text) ${localize(LocalizationKey.commandsWysiwygCommandStrikethroughLabel)}`,
detail: localize(LocalizationKey.commandsWysiwygCommandStrikethroughDetail),
alwaysShow: true
}
];
const option = await window.showQuickPick([...qpItems], {
title: l10n.t(LocalizationKey.commandsWysiwygQuickPickTitle),
placeHolder: l10n.t(LocalizationKey.commandsWysiwygQuickPickPlaceholder),
title: localize(LocalizationKey.commandsWysiwygQuickPickTitle),
placeHolder: localize(LocalizationKey.commandsWysiwygQuickPickPlaceholder),
canPickMany: false,
ignoreFocusOut: true
});
@@ -147,6 +148,15 @@ export class Wysiwyg {
);
}
/**
* Retrieves the document type based on the file extension.
* @param filePath - The path of the file.
* @returns The document type ('asciidoc' or 'markdown').
*/
public static getDocType(filePath: string): DocType {
return filePath.endsWith('.adoc') ? 'asciidoc' : 'markdown';
}
/**
* Add the markup to the content
* @param type
@@ -161,11 +171,12 @@ export class Wysiwyg {
const selection = editor.selection;
const hasTextSelection = !selection.isEmpty;
const docType: DocType = Wysiwyg.getDocType(editor.document.fileName);
if (type === MarkupType.hyperlink) {
return this.addHyperlink(editor, selection);
return this.addHyperlink(editor, selection, docType);
}
const markers = this.getMarkers(type);
const markers = this.getMarkers(type, docType);
if (!markers) {
return;
}
@@ -175,13 +186,13 @@ export class Wysiwyg {
if (hasTextSelection) {
// Replace the selection and surround with the markup
const selectionText = editor.document.getText(selection);
const txt = await this.insertText(markers, type, selectionText);
const txt = await this.insertText(markers, type, selectionText, docType);
editor.edit((builder) => {
builder.replace(selection, txt);
});
} else {
const txt = await this.insertText(markers, type);
const txt = await this.insertText(markers, type, null, docType);
// Insert the markers where cursor is located.
const markerLength = this.isMarkupWrapping(type) ? txt.length + 1 : markers.length;
@@ -198,6 +209,10 @@ export class Wysiwyg {
newPosition = crntSelection.with(crntSelection.line + 1, 0);
}
if (type === MarkupType.blockquote && docType === 'asciidoc') {
newPosition = crntSelection.with(crntSelection.line + 1, 0);
}
editor.selection = new Selection(newPosition, newPosition);
}
}
@@ -206,28 +221,39 @@ export class Wysiwyg {
* Add a hyperlink to the content
* @returns void
*/
private static async addHyperlink(editor: TextEditor, selection: Selection) {
private static async addHyperlink(
editor: TextEditor,
selection: Selection,
docType: DocType = 'markdown'
) {
const hasTextSelection = !selection.isEmpty;
const linkText = hasTextSelection ? editor.document.getText(selection) : '';
const link = await window.showInputBox({
title: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputTitle),
placeHolder: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputPrompt),
prompt: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputPrompt),
title: localize(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputTitle),
placeHolder: localize(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputPrompt),
prompt: localize(LocalizationKey.commandsWysiwygAddHyperlinkHyperlinkInputPrompt),
value: linkText,
ignoreFocusOut: true
});
const text = await window.showInputBox({
title: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkTextInputTitle),
prompt: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkTextInputPrompt),
placeHolder: l10n.t(LocalizationKey.commandsWysiwygAddHyperlinkTextInputPrompt),
title: localize(LocalizationKey.commandsWysiwygAddHyperlinkTextInputTitle),
prompt: localize(LocalizationKey.commandsWysiwygAddHyperlinkTextInputPrompt),
placeHolder: localize(LocalizationKey.commandsWysiwygAddHyperlinkTextInputPrompt),
value: linkText,
ignoreFocusOut: true
});
if (link) {
const txt = `[${text || link}](${link})`;
let txt = `[${text || link}](${link})`;
if (docType === 'asciidoc') {
txt = !link.startsWith('http') ? `link:${link}` : link;
if (text) {
txt = `${txt}[${text}]`;
}
}
if (hasTextSelection) {
editor.edit((builder) => {
@@ -255,14 +281,23 @@ export class Wysiwyg {
* @param type
* @returns
*/
private static isMarkupWrapping(type: MarkupType) {
return (
type === MarkupType.blockquote ||
type === MarkupType.heading ||
type === MarkupType.unorderedList ||
type === MarkupType.orderedList ||
type === MarkupType.taskList
);
private static isMarkupWrapping(type: MarkupType, docType: DocType = 'markdown') {
if (docType === 'markdown') {
return (
type === MarkupType.blockquote ||
type === MarkupType.heading ||
type === MarkupType.unorderedList ||
type === MarkupType.orderedList ||
type === MarkupType.taskList
);
} else if (docType === 'asciidoc') {
return (
type === MarkupType.heading ||
type === MarkupType.unorderedList ||
type === MarkupType.orderedList ||
type === MarkupType.taskList
);
}
}
/**
@@ -271,17 +306,18 @@ export class Wysiwyg {
private static async insertText(
marker: string | undefined,
type: MarkupType,
text: string | null = null
text: string | null = null,
docType: DocType = 'markdown'
) {
const crntText = text || this.lineBreak(type);
const crntText = text || this.lineBreak(type, docType);
if (this.isMarkupWrapping(type)) {
if (this.isMarkupWrapping(type, docType)) {
if (type === MarkupType.heading) {
const headingLvl = await window.showQuickPick(
['Heading 1', 'Heading 2', 'Heading 3', 'Heading 4', 'Heading 5', 'Heading 6'],
{
title: l10n.t(LocalizationKey.commandsWysiwygInsertTextHeadingInputTitle),
placeHolder: l10n.t(LocalizationKey.commandsWysiwygInsertTextHeadingInputPlaceholder),
title: localize(LocalizationKey.commandsWysiwygInsertTextHeadingInputTitle),
placeHolder: localize(LocalizationKey.commandsWysiwygInsertTextHeadingInputPlaceholder),
canPickMany: false,
ignoreFocusOut: true
}
@@ -298,9 +334,12 @@ export class Wysiwyg {
return lines.join('\n');
}
if (type === MarkupType.orderedList) {
if (type === MarkupType.orderedList && docType === 'markdown') {
const lines = crntText.split('\n').map((line, idx) => `${idx + 1}. ${line}`);
return lines.join('\n');
} else if (type === MarkupType.orderedList && docType === 'asciidoc') {
const lines = crntText.split('\n').map((line) => `${marker} ${line}`);
return lines.join('\n');
}
return `${marker} ${crntText}`;
@@ -314,9 +353,11 @@ export class Wysiwyg {
* @param type
* @returns
*/
private static lineBreak(type: MarkupType) {
private static lineBreak(type: MarkupType, docType: DocType = 'markdown') {
if (type === MarkupType.codeblock) {
return `\n\n`;
} else if (type === MarkupType.blockquote && docType === 'asciidoc') {
return `\n\n`;
}
return '';
}
@@ -326,30 +367,57 @@ export class Wysiwyg {
* @param type
* @returns
*/
private static getMarkers(type: MarkupType) {
switch (type) {
case MarkupType.bold:
return `**`;
case MarkupType.italic:
return `*`;
case MarkupType.strikethrough:
return `~~`;
case MarkupType.code:
return '`';
case MarkupType.codeblock:
return '```';
case MarkupType.blockquote:
return '>';
case MarkupType.heading:
return '#';
case MarkupType.unorderedList:
return '-';
case MarkupType.orderedList:
return '1.';
case MarkupType.taskList:
return '- [ ]';
default:
return;
private static getMarkers(type: MarkupType, docType: DocType = 'markdown') {
if (docType === 'markdown') {
switch (type) {
case MarkupType.bold:
return `**`;
case MarkupType.italic:
return `*`;
case MarkupType.strikethrough:
return `~~`;
case MarkupType.code:
return '`';
case MarkupType.codeblock:
return '```';
case MarkupType.blockquote:
return '>';
case MarkupType.heading:
return '#';
case MarkupType.unorderedList:
return '-';
case MarkupType.orderedList:
return '1.';
case MarkupType.taskList:
return '- [ ]';
default:
return;
}
} else if (docType === 'asciidoc') {
switch (type) {
case MarkupType.bold:
return `*`;
case MarkupType.italic:
return `_`;
case MarkupType.strikethrough:
return `~`;
case MarkupType.code:
return '`';
case MarkupType.codeblock:
return '----';
case MarkupType.blockquote:
return '____';
case MarkupType.heading:
return '=';
case MarkupType.unorderedList:
return '*';
case MarkupType.orderedList:
return '.';
case MarkupType.taskList:
return '* [ ]';
default:
return;
}
}
}
}

View File

@@ -1,4 +1,13 @@
import { ProgressLocation, Uri, commands, window, workspace } from 'vscode';
import {
ProgressLocation,
QuickPickItem,
QuickPickItemKind,
QuickPickOptions,
Uri,
commands,
window,
workspace
} from 'vscode';
import {
ArticleHelper,
ContentType,
@@ -12,12 +21,11 @@ import {
import { COMMAND_NAME, SETTING_CONTENT_I18N } from '../constants';
import { ContentFolder, Field, I18nConfig, ContentType as IContentType } from '../models';
import { join, parse } from 'path';
import { existsAsync } from '../utils';
import { existsAsync, getDescriptionField, getTitleField } from '../utils';
import { Folders } from '.';
import { ParsedFrontMatter } from '../parsers';
import { PagesListener } from '../listeners/dashboard';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../localization';
import { LocalizationKey, localize } from '../localization';
import { Translations } from '../services/Translations';
export class i18n {
@@ -32,6 +40,7 @@ export class i18n {
const subscriptions = Extension.getInstance().subscriptions;
subscriptions.push(commands.registerCommand(COMMAND_NAME.i18n.create, i18n.create));
subscriptions.push(commands.registerCommand(COMMAND_NAME.i18n.createOrOpen, i18n.createOrOpen));
i18n.clearFiles();
}
@@ -264,7 +273,7 @@ export class i18n {
}
if (!fileUri) {
Notifications.warning(l10n.t(LocalizationKey.commandsI18nCreateWarningNoFileSelected));
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoFileSelected));
return;
}
@@ -274,19 +283,19 @@ export class i18n {
const pageFolder = await Folders.getPageFolderByFilePath(fileUri.fsPath);
if (!pageFolder || !pageFolder.localeSourcePath) {
Notifications.error(l10n.t(LocalizationKey.commandsI18nCreateErrorNoContentFolder));
Notifications.error(localize(LocalizationKey.commandsI18nCreateErrorNoContentFolder));
return;
}
const i18nSettings = await i18n.getSettings(fileUri.fsPath);
if (!i18nSettings) {
Notifications.warning(l10n.t(LocalizationKey.commandsI18nCreateWarningNoConfig));
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoConfig));
return;
}
const sourceLocale = await i18n.getLocale(fileUri.fsPath);
if (!sourceLocale || !sourceLocale.locale) {
Notifications.warning(l10n.t(LocalizationKey.commandsI18nCreateErrorNoLocaleDefinition));
Notifications.warning(localize(LocalizationKey.commandsI18nCreateErrorNoLocaleDefinition));
return;
}
@@ -300,15 +309,15 @@ export class i18n {
});
if (targetLocales.length === 0) {
Notifications.warning(l10n.t(LocalizationKey.commandsI18nCreateErrorNoLocales));
Notifications.warning(localize(LocalizationKey.commandsI18nCreateErrorNoLocales));
return;
}
const locale = await window.showQuickPick(
targetLocales.map((i18n) => i18n.title || i18n.locale),
{
title: l10n.t(LocalizationKey.commandsI18nCreateQuickPickTitle),
placeHolder: l10n.t(LocalizationKey.commandsI18nCreateQuickPickPlaceHolder),
title: localize(LocalizationKey.commandsI18nCreateQuickPickTitle),
placeHolder: localize(LocalizationKey.commandsI18nCreateQuickPickPlaceHolder),
ignoreFocusOut: true
}
);
@@ -321,19 +330,19 @@ export class i18n {
(i18n) => i18n.title === locale || i18n.locale === locale
);
if (!targetLocale || !targetLocale.path) {
Notifications.warning(l10n.t(LocalizationKey.commandsI18nCreateWarningNoConfig));
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoConfig));
return;
}
let article = await ArticleHelper.getFrontMatterByPath(fileUri.fsPath);
if (!article) {
Notifications.warning(l10n.t(LocalizationKey.commandsI18nCreateWarningNoFile));
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoFile));
return;
}
const contentType = await ArticleHelper.getContentType(article);
if (!contentType) {
Notifications.warning(l10n.t(LocalizationKey.commandsI18nCreateWarningNoContentType));
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoContentType));
return;
}
@@ -365,7 +374,7 @@ export class i18n {
const newFilePath = join(i18nDir, fileInfo.base);
if (await existsAsync(newFilePath)) {
Notifications.error(l10n.t(LocalizationKey.commandsI18nCreateErrorFileExists));
Notifications.error(localize(LocalizationKey.commandsI18nCreateErrorFileExists));
return;
}
@@ -384,7 +393,188 @@ export class i18n {
PagesListener.refresh();
Notifications.info(
l10n.t(
localize(
LocalizationKey.commandsI18nCreateSuccessCreated,
sourceLocale.title || sourceLocale.locale
)
);
}
/**
* This method handles the process of creating a new translation file if it doesn't exist,
* or opening an existing translation file if it's already present.
* @param filePath The path of the file where the new content file should be created or being switched to. Behaves like `create` if not provided.
*/
private static async createOrOpen(fileUri?: Uri | string) {
if (!fileUri) {
const filePath = ArticleHelper.getActiveFile();
fileUri = filePath ? Uri.file(filePath) : undefined;
}
if (!fileUri) {
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoFileSelected));
return;
}
if (typeof fileUri === 'string') {
fileUri = Uri.file(fileUri);
}
const pageFolder = await Folders.getPageFolderByFilePath(fileUri.fsPath);
if (!pageFolder || !pageFolder.localeSourcePath) {
Notifications.error(localize(LocalizationKey.commandsI18nCreateErrorNoContentFolder));
return;
}
let article = await ArticleHelper.getFrontMatterByPath(fileUri.fsPath);
if (!article) {
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoFile));
return;
}
const contentType = await ArticleHelper.getContentType(article);
if (!contentType) {
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoContentType));
return;
}
const i18nSettings = await i18n.getSettings(fileUri.fsPath);
if (!i18nSettings) {
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoConfig));
return;
}
const sourceLocale = await i18n.getLocale(fileUri.fsPath);
if (!sourceLocale || !sourceLocale.locale) {
Notifications.warning(localize(LocalizationKey.commandsI18nCreateErrorNoLocaleDefinition));
return;
}
// Determine translation file paths
const fileInfo = parse(fileUri.fsPath);
let pageBundleDir = '';
if (await ArticleHelper.isPageBundle(fileUri.fsPath)) {
const dir = ArticleHelper.getPageFolderFromBundlePath(fileUri.fsPath);
pageBundleDir = fileUri.fsPath.replace(dir, '');
pageBundleDir = join(parse(pageBundleDir).dir);
}
// Gather target locales & metadata
const translations = (await i18n.getTranslations(fileUri.fsPath)) || {};
const targetLocales = i18nSettings
.filter((i18n) => {
return i18n.path && i18n.locale !== sourceLocale.locale;
})
.map((i18n) => {
return {
...i18n,
dir: join(pageFolder.localeSourcePath!, i18n.path!, pageBundleDir),
absolutePath: join(
pageFolder.localeSourcePath!,
i18n.path!,
pageBundleDir,
fileInfo.base
),
relativePath: join(i18n.path!, pageBundleDir, fileInfo.base)
};
})
.sort((a, b) => (a.title || a.locale).localeCompare(b.title || b.locale));
if (targetLocales.length === 0) {
Notifications.warning(localize(LocalizationKey.commandsI18nCreateErrorNoLocales));
return;
}
// Configure quick pick items & options
const existingTargetLocales = targetLocales.filter((i18n) => translations[i18n.locale]);
const newTargetLocales = targetLocales.filter((i18n) => !translations[i18n.locale]);
const quickPickItems: QuickPickItem[] = [
...(existingTargetLocales.length
? [
{
label: localize(LocalizationKey.commandsI18nCreateOrOpenQuickPickCategoryExisting),
kind: QuickPickItemKind.Separator
},
...existingTargetLocales.map((i18n) => ({
label: i18n.title || i18n.locale,
detail: localize(
LocalizationKey.commandsI18nCreateOrOpenQuickPickActionOpen,
i18n.relativePath
)
}))
]
: []),
...(newTargetLocales.length
? [
{
label: localize(LocalizationKey.commandsI18nCreateOrOpenQuickPickCategoryNew),
kind: QuickPickItemKind.Separator
},
...newTargetLocales.map((i18n) => ({
label: i18n.title || i18n.locale,
detail: `$(file-add) ${localize(
LocalizationKey.commandsI18nCreateOrOpenQuickPickActionCreate,
i18n.relativePath
)}`
}))
]
: [])
];
const quickPickOptions: QuickPickOptions = {
title: localize(LocalizationKey.commandsI18nCreateOrOpenQuickPickTitle),
ignoreFocusOut: true,
matchOnDetail: true
};
const localeItem = await window.showQuickPick<QuickPickItem>(quickPickItems, quickPickOptions);
const locale = localeItem?.label;
if (!locale) {
return;
}
const targetLocale = targetLocales.find(
(i18n) => i18n.title === locale || i18n.locale === locale
);
if (!targetLocale || !targetLocale.path) {
Notifications.warning(localize(LocalizationKey.commandsI18nCreateWarningNoConfig));
return;
}
// If it exists, open the translation file
if (await existsAsync(targetLocale.absolutePath)) {
await openFileInEditor(targetLocale.absolutePath);
return;
}
// If it doesn't exist, create the new translation file & update front matter
if (!(await existsAsync(targetLocale.dir))) {
await workspace.fs.createDirectory(Uri.file(targetLocale.dir));
}
article = await i18n.updateFrontMatter(
article,
fileUri.fsPath,
contentType,
sourceLocale,
targetLocale,
targetLocale.dir
);
if (sourceLocale?.locale) {
article = await i18n.translate(article, sourceLocale, targetLocale);
}
const newFileUri = Uri.file(targetLocale.absolutePath);
await workspace.fs.writeFile(
newFileUri,
Buffer.from(ArticleHelper.stringifyFrontMatter(article.content, article.data))
);
await openFileInEditor(targetLocale.absolutePath);
PagesListener.refresh();
Notifications.info(
localize(
LocalizationKey.commandsI18nCreateSuccessCreated,
sourceLocale.title || sourceLocale.locale
)
@@ -403,17 +593,20 @@ export class i18n {
sourceLocale: I18nConfig,
targetLocale: I18nConfig
) {
return new Promise<ParsedFrontMatter>(async (resolve) => {
await window.withProgress(
return new Promise<ParsedFrontMatter>((resolve) => {
window.withProgress(
{
location: ProgressLocation.Notification,
title: l10n.t(LocalizationKey.commandsI18nTranslateProgressTitle),
title: localize(LocalizationKey.commandsI18nTranslateProgressTitle),
cancellable: false
},
async () => {
try {
const title = article.data.title || '';
const description = article.data.description || '';
const titleField = getTitleField();
const descriptionField = getDescriptionField();
const title = article.data[titleField] || '';
const description = article.data[descriptionField] || '';
const content = article.content || '';
const text = [title, description, content];
@@ -428,8 +621,8 @@ export class i18n {
return;
}
article.data.title = article.data.title ? translations[0] : '';
article.data.description = article.data.description ? translations[1] : '';
article.data[titleField] = article.data[titleField] ? translations[0] : '';
article.data[descriptionField] = article.data[descriptionField] ? translations[1] : '';
article.content = article.content ? translations[2] : '';
} catch (error) {
Notifications.error(`${(error as Error).message}`);

View File

@@ -10,5 +10,7 @@ export * from './Preview';
export * from './Project';
export * from './Settings';
export * from './StatusListener';
export * from './Taxonomy';
export * from './Template';
export * from './Wysiwyg';
export * from './i18n';

View File

@@ -0,0 +1,26 @@
import * as React from 'react';
import { Tooltip as TT } from 'react-tooltip'
export interface ITooltipProps {
id: string;
render?: () => React.ReactNode;
}
export const Tooltip: React.FunctionComponent<ITooltipProps> = ({
id,
render
}: React.PropsWithChildren<ITooltipProps>) => {
const tooltipClasses = `!py-[2px] !px-[8px] !rounded-[3px] !border-[var(--vscode-editorHoverWidget-border)] !border !border-solid !bg-[var(--vscode-editorHoverWidget-background)] !text-[var(--vscode-editorHoverWidget-foreground)] !font-normal !opacity-100 shadow-[0_2px_8px_var(--vscode-widget-shadow)] text-left`;
return (
<TT
id={id}
className={tooltipClasses}
style={{
fontSize: '12px',
lineHeight: '19px'
}}
render={render} />
);
};

View File

@@ -30,6 +30,7 @@ function Num({
<LabelField label={label} id={id} required={props.required} />
<input
className='block w-full py-2 pr-2 sm:text-sm appearance-none disabled:opacity-50 rounded bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] placeholder-[var(--vscode-input-placeholderForeground)] border-[var(--frontmatter-border)] focus:border-[var(--vscode-focusBorder)] focus:outline-0'
disabled={disabled}
id={id}
max={max}

View File

@@ -42,6 +42,7 @@ function Select({
...props
}: SelectFieldProps) {
const multiple = fieldType === Array;
return (
<div className="autoform__select_field" {...filterDOMProps(props)}>
<LabelField label={label} id={id} required={required} />
@@ -84,11 +85,12 @@ function Select({
}}
ref={inputRef}
value={value ?? ''}
className='text-[var(--vscode-foreground)] bg-[var(--vscode-list-activeSelectionBackground)] rounded-[2px] active:border-transparent disabled:opacity-40 disabled:cursor-not-allowed focus:outline-none'
style={{ width: '100%', padding: '0.5rem' }}
>
{(!!placeholder || !required || value === undefined) && !multiple && (
{(!required || value === undefined) && !multiple && (
<option value="" disabled={required} hidden={required}>
{placeholder || label}
{""}
</option>
)}

View File

@@ -0,0 +1,12 @@
import { FEATURE_FLAG } from './Features';
export const DEFAULT_PANEL_FEATURE_FLAGS = Object.values(FEATURE_FLAG.panel).filter(
(v) => v !== FEATURE_FLAG.panel.globalSettings
);
export const DEFAULT_DASHBOARD_FEATURE_FLAGS = [
FEATURE_FLAG.dashboard.data.view,
FEATURE_FLAG.dashboard.taxonomy.view,
FEATURE_FLAG.dashboard.snippets.view,
FEATURE_FLAG.dashboard.snippets.manage
];

View File

@@ -3,5 +3,8 @@ export const DefaultFields = {
LastModified: `lastmod`,
Description: `description`,
Title: `title`,
Slug: `slug`
Slug: `slug`,
Type: `type`,
ContentType: `fmContentType`,
Keywords: `keywords`
};

View File

@@ -1,10 +1,10 @@
const extensionName = 'frontMatter';
export const EXTENSION_COMMAND_PREFIX = 'frontMatter';
export const EXTENSION_ID = 'eliostruyf.vscode-front-matter';
export const EXTENSION_BETA_ID = 'eliostruyf.vscode-front-matter-beta';
export const getCommandName = (command: string) => {
return `${extensionName}.${command}`;
return `${EXTENSION_COMMAND_PREFIX}.${command}`;
};
export const COMMAND_NAME = {
@@ -27,6 +27,7 @@ export const COMMAND_NAME = {
initTemplate: getCommandName('initTemplate'),
collapseSections: getCommandName('collapseSections'),
preview: getCommandName('preview'),
docs: getCommandName('docs'),
chatbot: getCommandName('chatbot'),
dashboard: getCommandName('dashboard'),
dashboardMedia: getCommandName('dashboard.media'),
@@ -69,7 +70,8 @@ export const COMMAND_NAME = {
// i18n
i18n: {
create: getCommandName('i18n.create')
create: getCommandName('i18n.create'),
createOrOpen: getCommandName('i18n.createOrOpen')
},
// Project

View File

@@ -4,10 +4,10 @@ export const FEATURE_FLAG = {
seo: 'panel.seo',
actions: 'panel.actions',
metadata: 'panel.metadata',
recentlyModified: 'panel.recentlyModified',
otherActions: 'panel.otherActions',
contentType: 'panel.contentType',
gitActions: 'panel.gitActions'
gitActions: 'panel.gitActions',
recentlyModified: 'panel.recentlyModified',
otherActions: 'panel.otherActions'
},
dashboard: {
snippets: {

View File

@@ -14,8 +14,20 @@ export const DOCS_SUBMODULES = 'https://frontmatter.codes/docs/git-integration#g
export const WEBSITE_LINKS = {
root: 'https://frontmatter.codes',
api: {
metrics: 'https://frontmatter.codes/api/metrics',
ai: 'https://frontmatter.codes/api/ai'
baseUrl: 'https://api.frontmatter.codes',
endpoints: {
ai: {
description: '/ai/description',
taxonomy: '/ai/taxonomy',
title: '/ai/title'
},
chat: {
init: '/ai-init',
message: '/ai-chat',
feedback: '/ai-feedback'
},
backers: '/v2/backers'
}
},
docs: {
dataDashboard: 'https://frontmatter.codes/docs/dashboard/datafiles-view',

View File

@@ -1,56 +0,0 @@
export const TelemetryEvent = {
activate: 'activate',
initialization: 'initialization',
registerFolder: 'registerFolder',
unregisterFolder: 'unregisterFolder',
promoteSettings: 'promoteSettings',
// Commands
openContentDashboard: 'openContentDashboard',
openMediaDashboard: 'openMediaDashboard',
openDataDashboard: 'openDataDashboard',
openSnippetsDashboard: 'openSnippetsDashboard',
openTaxonomyDashboard: 'openTaxonomyDashboard',
closeDashboard: 'closeDashboard',
// Other actions
generateSlug: 'generateSlug',
createContentFromTemplate: 'createContentFromTemplate',
createContentFromContentType: 'createContentFromContentType',
addMediaFolder: 'addMediaFolder',
openPreview: 'openPreview',
uploadMedia: 'uploadMedia',
refreshMedia: 'refreshMedia',
deleteMedia: 'deleteMedia',
insertContentSnippet: 'insertContentSnippet',
insertMediaToContent: 'insertMediaToContent',
insertFileToContent: 'insertFileToContent',
updateMediaMetadata: 'updateMediaMetadata',
openPanelWebview: 'openPanelWebview',
// Chatbot
openChatbot: 'openChatbot',
// Content types
generateContentType: 'generateContentType',
addMissingFields: 'addMissingFields',
setContentType: 'setContentType',
// Custom scripts
runCustomScript: 'runCustomScript',
runMediaScript: 'runMediaScript',
// Webviews
webviewWelcomeScreen: 'webviewWelcomeScreen',
webviewMediaView: 'webviewMediaView',
webviewDataView: 'webviewDataView',
webviewContentsView: 'webviewContentsView',
webviewSnippetsView: 'webviewSnippetsView',
webviewTaxonomyDashboard: 'webviewTaxonomyDashboard',
webviewSettings: 'webviewSettings',
webviewUnknown: 'webviewUnknown',
// Git
gitSync: 'gitSync',
gitFetch: 'gitFetch'
};

View File

@@ -1,4 +1,5 @@
export * from './ContentType';
export * from './DefaultFeatureFlags';
export * from './DefaultFieldValues';
export * from './DefaultFields';
export * from './DefaultFileTypes';
@@ -17,7 +18,6 @@ export * from './SentryIgnore';
export * from './Snippet';
export * from './SsgScripts';
export * from './StaticFolderPlaceholder';
export * from './TelemetryEvent';
export * from './Templates';
export * from './charCode';
export * from './charMap';

View File

@@ -13,6 +13,7 @@ export const SETTING_GLOBAL_NOTIFICATIONS = 'global.notifications';
export const SETTING_GLOBAL_NOTIFICATIONS_DISABLED = 'global.disabledNotifications';
export const SETTING_GLOBAL_MODES = 'global.modes';
export const SETTING_GLOBAL_ACTIVE_MODE = 'global.activeMode';
export const SETTING_GLOBAL_TIMEZONE = 'global.timezone';
export const SETTING_TAXONOMY_TAGS = 'taxonomy.tags';
export const SETTING_TAXONOMY_CATEGORIES = 'taxonomy.categories';
@@ -45,8 +46,7 @@ export const SETTING_TEMPLATES_FOLDER = 'templates.folder';
export const SETTING_TEMPLATES_PREFIX = 'templates.prefix';
export const SETTING_TEMPLATES_ENABLED = 'templates.enabled';
export const SETTING_TELEMETRY_DISABLE = 'telemetry.disable';
export const SETTING_PANEL_OPEN_ON_SUPPORTED_FILE = 'panel.openOnSupportedFile';
export const SETTING_PANEL_FREEFORM = 'panel.freeform';
export const SETTING_PANEL_ACTIONS_DISABLED = 'panel.actions.disabled';
@@ -63,6 +63,7 @@ export const SETTING_CONTENT_STATIC_FOLDER = 'content.publicFolder';
export const SETTING_CONTENT_FRONTMATTER_HIGHLIGHT = 'content.fmHighlight';
export const SETTING_CONTENT_DRAFT_FIELD = 'content.draftField';
export const SETTING_CONTENT_SORTING = 'content.sorting';
export const SETTING_CONTENT_GROUPING = 'content.grouping';
export const SETTING_CONTENT_FILTERS = 'content.filters';
export const SETTING_CONTENT_WYSIWYG = 'content.wysiwyg';
export const SETTING_CONTENT_PLACEHOLDERS = 'content.placeholders';
@@ -115,6 +116,8 @@ export const SETTING_SNIPPETS_WRAPPER = 'snippets.wrapper.enabled';
export const SETTING_WEBSITE_URL = 'website.host';
export const SETTING_COPILOT_FAMILY = 'copilot.family';
export const SETTING_LOGGING = 'logging';
/**

View File

@@ -42,6 +42,8 @@ export enum DashboardMessage {
insertMedia = 'insertMedia',
updateMediaMetadata = 'updateMediaMetadata',
createMediaFolder = 'createMediaFolder',
updateMediaFolder = 'updateMediaFolder',
deleteMediaFolder = 'deleteMediaFolder',
insertFile = 'insertFile',
createHexoAssetFolder = 'createHexoAssetFolder',
getUnmappedMedia = 'getUnmappedMedia',
@@ -50,6 +52,7 @@ export enum DashboardMessage {
// Data dashboard
getDataEntries = 'getDataEntries',
putDataEntries = 'putDataEntries',
createDataFile = 'createDataFile',
// Snippets dashboard
insertSnippet = 'insertSnippet',
@@ -74,7 +77,6 @@ export enum DashboardMessage {
setState = 'setState',
getState = 'getState',
runCustomScript = 'runCustomScript',
sendTelemetry = 'sendTelemetry',
showNotification = 'showNotification',
setTitle = 'setTitle',

View File

@@ -54,7 +54,7 @@ export const App: React.FunctionComponent<IAppProps> = ({
return isAllowed(mode?.features || [], FEATURE_FLAG.dashboard.taxonomy.view);
}, [mode?.features]);
const checkDevMode = (retry: number = 0) => {
const checkDevMode = (retry = 0) => {
if (!window.fmExternal) {
if (retry < 5) {
setTimeout(() => checkDevMode(retry + 1), 150);

View File

@@ -10,11 +10,12 @@ import { AiInitResponse } from './models/AiInitResponse';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { messageHandler } from '@estruyf/vscode/dist/client';
import { GeneralCommands } from '../../../constants';
import { GeneralCommands, WEBSITE_LINKS } from '../../../constants';
import { l10nJsonFormat } from '@vscode/l10n';
export interface IChatbotProps { }
export const Chatbot: React.FunctionComponent<IChatbotProps> = ({ }: React.PropsWithChildren<IChatbotProps>) => {
export const Chatbot: React.FunctionComponent<IChatbotProps> = () => {
const { aiUrl } = useSettingsContext();
const [company, setCompany] = React.useState<string | undefined>(undefined);
const [chatId, setChatId] = React.useState<number | undefined>(undefined);
@@ -27,7 +28,7 @@ export const Chatbot: React.FunctionComponent<IChatbotProps> = ({ }: React.Props
const init = async () => {
setLoading(true);
messageHandler.request<any>(GeneralCommands.toVSCode.getLocalization).then((data) => {
messageHandler.request<l10nJsonFormat>(GeneralCommands.toVSCode.getLocalization).then((data) => {
if (data) {
l10n.config({
contents: data
@@ -36,7 +37,7 @@ export const Chatbot: React.FunctionComponent<IChatbotProps> = ({ }: React.Props
setLocaleReady(true);
});
const initResponse = await fetch(`${aiUrl}/api/ai-init`);
const initResponse = await fetch(`${aiUrl}${WEBSITE_LINKS.api.endpoints.chat.init}`);
if (!initResponse.ok) {
return;
@@ -70,7 +71,7 @@ export const Chatbot: React.FunctionComponent<IChatbotProps> = ({ }: React.Props
return;
}
const response = await fetch(`${aiUrl}/api/ai-chat`, {
const response = await fetch(`${aiUrl}${WEBSITE_LINKS.api.endpoints.chat.message}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',

View File

@@ -3,6 +3,7 @@ import { HandThumbDownIcon, HandThumbUpIcon } from '@heroicons/react/24/outline'
import { HandThumbDownIcon as ThumbDownSolidIcon, HandThumbUpIcon as ThumbUpSolidIcon } from '@heroicons/react/24/solid';
import { useCallback } from 'react';
import { useSettingsContext } from '../../providers/SettingsProvider';
import { WEBSITE_LINKS } from '../../../constants';
export interface IFeedbackProps {
answerId: number;
@@ -28,7 +29,7 @@ export const Feedback: React.FunctionComponent<IFeedbackProps> = ({
}, []);
const callVote = useCallback(async (vote: boolean) => {
await fetch(`${aiUrl}/api/ai-feedback`, {
await fetch(`${aiUrl}${WEBSITE_LINKS.api.endpoints.chat.feedback}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',

View File

@@ -1,33 +0,0 @@
import * as React from 'react';
export interface IButtonProps {
secondary?: boolean;
disabled?: boolean;
className?: string;
onClick: () => void;
}
export const Button: React.FunctionComponent<IButtonProps> = ({
onClick,
className,
disabled,
secondary,
children
}: React.PropsWithChildren<IButtonProps>) => {
return (
<button
type="button"
className={`${className || ''
} inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium focus:outline-none rounded disabled:opacity-50 ${secondary ?
`bg-[var(--vscode-button-secondaryBackground)] text-[--vscode-button-secondaryForeground] hover:bg-[var(--vscode-button-secondaryHoverBackground)]` :
`bg-[var(--frontmatter-button-background)] text-[var(--vscode-button-foreground)] hover:bg-[var(--frontmatter-button-hoverBackground)]`
}
`}
onClick={onClick}
disabled={disabled}
>
{children}
</button>
);
};

View File

@@ -1,6 +1,6 @@
import * as React from 'react';
import useSelectedItems from '../../hooks/useSelectedItems';
import { VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
import { Checkbox as VSCodeCheckbox } from 'vscrui';
import { useMemo } from 'react';
export interface IItemSelectionProps {
@@ -24,11 +24,11 @@ export const ItemSelection: React.FunctionComponent<IItemSelectionProps> = ({
return (
<div className={`${cssNames} group-hover:block`}>
<VSCodeCheckbox
style={{
boxShadow: show ? "" : "0 0 3px var(--frontmatter-border-preserve)"
}}
onClick={(e: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
className={show ? "" : " shadow-[0_0_3px_var(--frontmatter-border-preserve)]"}
onClick={(e) => {
e.stopPropagation();
}}
onChange={() => {
onMultiSelect(filePath);
}}
checked={selectedFiles.includes(filePath)} />

View File

@@ -10,7 +10,7 @@ import usePages from '../../hooks/usePages';
import { useCallback, useEffect, useState } from 'react';
import { Messenger, messageHandler } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { GeneralCommands, TelemetryEvent } from '../../../constants';
import { GeneralCommands } from '../../../constants';
import { PageLayout } from '../Layout/PageLayout';
import { FilesProvider } from '../../providers/FilesProvider';
import { Alert } from '../Modals/Alert';
@@ -67,10 +67,6 @@ export const Contents: React.FunctionComponent<IContentsProps> = ({
}, [JSON.stringify(pageItems)]);
useEffect(() => {
Messenger.send(DashboardMessage.sendTelemetry, {
event: TelemetryEvent.webviewContentsView
});
Messenger.send(DashboardMessage.setTitle, l10n.t(LocalizationKey.dashboardHeaderTabsContents));
}, []);

View File

@@ -38,7 +38,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({
date: pageData.date,
title: pageData.title,
description: pageData.description,
type: pageData.type,
type: pageData.fmContentType,
pageData
});

View File

@@ -6,12 +6,11 @@ import { useRecoilState, useRecoilValue } from 'recoil';
import { groupBy } from '../../../helpers/GroupBy';
import { FrontMatterIcon } from '../../../panelWebView/components/Icons/FrontMatterIcon';
import { GroupOption } from '../../constants/GroupOption';
import { GroupingSelector, PageAtom, ViewSelector } from '../../state';
import { GroupingSelector, PageAtom, PagedItems, ViewSelector } from '../../state';
import { Item } from './Item';
import { List } from './List';
import usePagination from '../../hooks/usePagination';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { LocalizationKey, localize } from '../../../localization';
import { PinnedItemsAtom } from '../../state/atom/PinnedItems';
import { messageHandler } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
@@ -34,6 +33,7 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({
const page = useRecoilValue(PageAtom);
const { pageSetNr } = usePagination(settings?.dashboardState.contents.pagination);
const view = useRecoilValue(ViewSelector);
const [, setPagedItems] = useRecoilState(PagedItems);
const pagedPages = useMemo(() => {
if (pageSetNr) {
@@ -53,13 +53,18 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({
const groupName = useCallback(
(groupId, groupedPages) => {
const count = groupedPages[groupId].length;
if (grouping === GroupOption.Draft) {
return `${groupId} (${groupedPages[groupId].length})`;
return `${groupId} (${count})`;
} else if (typeof grouping === 'string') {
const group = settings?.grouping?.find((g) => g.name === grouping);
const prefix = group?.title ? `${group.title}: ` : '';
return `${prefix}${groupId} (${count})`;
}
return `${GroupOption[grouping]}: ${groupId} (${groupedPages[groupId].length})`;
return `${GroupOption[grouping]}: ${groupId} (${count})`;
},
[grouping]
[grouping, settings?.grouping]
);
const { groupKeys, groupedPages } = useMemo(() => {
@@ -67,7 +72,18 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({
return { groupKeys: [], groupedPages: {} };
}
let groupedPages = groupBy(pages, grouping === GroupOption.Year ? 'fmYear' : 'fmDraft');
let groupName: string | undefined;
if (grouping === GroupOption.Year) {
groupName = 'fmYear';
} else if (grouping === GroupOption.Draft) {
groupName = 'fmDraft';
} else if (typeof grouping === 'string') {
groupName = grouping;
} else {
return { groupKeys: [], groupedPages: {} };
}
let groupedPages = groupBy(pages, groupName);
let groupKeys = Object.keys(groupedPages);
if (grouping === GroupOption.Year) {
@@ -95,11 +111,17 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({
...groupedPages,
}
}
} else {
groupKeys = groupKeys.sort();
}
return { groupKeys, groupedPages };
}, [pages, grouping, settings?.draftField]);
React.useEffect(() => {
setPagedItems(pagedPages.map((page) => page.fmFilePath));
}, [pagedPages]);
React.useEffect(() => {
messageHandler.request<string[]>(DashboardMessage.getPinnedItems).then((items) => {
setIsReady(true);
@@ -122,9 +144,11 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({
className={`h-32 mx-auto opacity-90 mb-8 text-[var(--vscode-editor-foreground)]`}
/>
{settings && settings?.contentFolders?.length > 0 ? (
<p className={`text-xl font-medium`}>{l10n.t(LocalizationKey.dashboardContentsOverviewNoMarkdown)}</p>
<p className={`text-xl font-medium`}>{localize(LocalizationKey.dashboardContentsOverviewNoMarkdown)}</p>
) : (
<p className={`text-lg font-medium`}>{l10n.t(LocalizationKey.dashboardContentsOverviewNoFolders)}</p>
<p className={`text-lg font-medium`}>{localize(LocalizationKey.dashboardContentsOverviewNoFolders)}</p>
)}
</div>
</div>
@@ -171,7 +195,8 @@ export const Overview: React.FunctionComponent<IOverviewProps> = ({
<div className='mb-8'>
<h1 className='text-xl flex space-x-2 items-center mb-4'>
<PinIcon className={`-rotate-45`} />
<span>{l10n.t(LocalizationKey.dashboardContentsOverviewPinned)}</span>
<span>{localize(LocalizationKey.dashboardContentsOverviewPinned)}</span>
</h1>
<List>
{pinnedPages.map((page, idx) => (

View File

@@ -53,7 +53,7 @@ export const DataForm: React.FunctionComponent<IDataFormProps> = ({
};
} catch (error) {
setError((error as Error).message);
return () => { };
return () => void 0;
}
};

View File

@@ -1,9 +1,9 @@
import * as React from 'react';
import { useForm } from 'uniforms';
import { Button } from '../Common/Button';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { SubmitField } from '../../../components/uniforms-frontmatter';
import { Button } from 'vscrui';
export interface IDataFormControlsProps {
model: any | null;
@@ -21,8 +21,8 @@ export const DataFormControls: React.FunctionComponent<IDataFormControlsProps> =
<SubmitField value={model ? `Update` : `Add`} />
<Button
className="ml-4"
secondary
className="ml-4 !py-2"
appearance="secondary"
onClick={() => {
if (onClear) {
onClear();

View File

@@ -5,34 +5,36 @@ import { SettingsSelector } from '../../state';
import { DataForm } from './DataForm';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { DataFile } from '../../../models/DataFile';
import { Messenger } from '@estruyf/vscode/dist/client';
import { messageHandler, Messenger } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { SponsorMsg } from '../Layout/SponsorMsg';
import { EventData } from '@estruyf/vscode';
import { DashboardCommand } from '../../DashboardCommand';
import { Button } from '../Common/Button';
import { arrayMoveImmutable } from 'array-move';
import { EmptyView } from './EmptyView';
import { Container } from './SortableContainer';
import { SortableItem } from './SortableItem';
import { ChevronRightIcon, CircleStackIcon } from '@heroicons/react/24/outline';
import { ChevronRightIcon, CircleStackIcon, EyeIcon, XMarkIcon } from '@heroicons/react/24/outline';
import { DataType } from '../../../models/DataType';
import { GeneralCommands, TelemetryEvent, WEBSITE_LINKS } from '../../../constants';
import { GeneralCommands, WEBSITE_LINKS } from '../../../constants';
import { NavigationItem } from '../Layout';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { LocalizationKey, localize } from '../../../localization';
import { DropdownMenu, DropdownMenuContent } from '../../../components/shadcn/Dropdown';
import { MenuButton, MenuItem } from '../Menu';
import { Transition } from '@headlessui/react';
import { DataFolder } from '../../../models';
import { ActionsBarItem } from '../Header/ActionsBarItem';
import { Spinner } from '../Common/Spinner';
import { openFile } from '../../utils/MessageHandlers';
import { Button } from 'vscrui';
export interface IDataViewProps { }
export const DataView: React.FunctionComponent<IDataViewProps> = (
_: React.PropsWithChildren<IDataViewProps>
) => {
export const DataView: React.FunctionComponent<IDataViewProps> = () => {
const [selectedData, setSelectedData] = useState<DataFile | null>(null);
const [selectedIndex, setSelectedIndex] = useState<number | null>(null);
const [dataEntries, setDataEntries] = useState<any | any[] | null>(null);
const [loading, setLoading] = useState<boolean>(false);
const settings = useRecoilValue(SettingsSelector);
const setSchema = (dataFile: DataFile) => {
@@ -64,14 +66,14 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
);
const onSubmit = useCallback(
(data: any) => {
(data: unknown) => {
if (selectedData?.singleEntry) {
// Needs to add a single entry
updateData(data);
return;
}
const dataClone: any[] = Object.assign([], dataEntries);
const dataClone: unknown[] = Object.assign([], dataEntries);
if (selectedIndex !== null && selectedIndex !== undefined) {
dataClone[selectedIndex] = data;
} else {
@@ -110,11 +112,23 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
entries: data
});
Messenger.send(DashboardMessage.showNotification, l10n.t(LocalizationKey.dashboardDataViewDataViewUpdateMessage));
Messenger.send(DashboardMessage.showNotification, localize(LocalizationKey.dashboardDataViewDataViewUpdateMessage));
},
[selectedData]
);
const createDataFile = (folder: DataFolder) => {
setLoading(true);
messageHandler.request<DataFile>(DashboardMessage.createDataFile, folder).then(dataFile => {
if (dataFile) {
setSchema(dataFile);
}
setLoading(false);
}).catch((_: any) => {
setLoading(false);
});
}
const dataEntry = useMemo(() => {
if (selectedData?.singleEntry) {
return dataEntries || {};
@@ -123,16 +137,44 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
return dataEntries && selectedIndex !== null && selectedIndex !== undefined
? dataEntries[selectedIndex]
: null;
}, [selectedData, , dataEntries, selectedIndex]);
}, [selectedData, dataEntries, selectedIndex]);
// Retrieve the data files, check if they have a schema or ID, if not, they shouldn't be shown
const dataFiles = useMemo(() => {
return (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[];
}, [settings?.dataFiles]);
const fileCreationFolders = useMemo(() => {
return (settings?.dataFolders || [])
.filter((folder) => folder.enableFileCreation);
}, [settings?.dataFolders]);
const hasOnlyDataCreationFolders = useMemo(() => (!dataFiles || dataFiles.length === 0) && (fileCreationFolders && fileCreationFolders.length > 0), [dataFiles, fileCreationFolders]);
useEffect(() => {
Messenger.listen(messageListener);
Messenger.send(DashboardMessage.setTitle, l10n.t(LocalizationKey.dashboardHeaderTabsData));
Messenger.send(DashboardMessage.sendTelemetry, {
event: TelemetryEvent.webviewDataView
});
Messenger.send(DashboardMessage.setTitle, localize(LocalizationKey.dashboardHeaderTabsData));
Messenger.send(GeneralCommands.toVSCode.logging.info, {
message: 'Data view loaded',
@@ -144,49 +186,27 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
};
}, []);
// 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 (
<div className="flex flex-col h-full overflow-auto inset-y-0">
<Header settings={settings} />
{dataFiles && dataFiles.length > 0 ? (
{(dataFiles && dataFiles.length > 0) || (fileCreationFolders && fileCreationFolders.length > 0) ? (
<div className={`relative w-full flex-grow mx-auto overflow-hidden`}>
{
!selectedData && (
!selectedData && (dataFiles && dataFiles.length > 0) && (
<div className={`flex w-64 flex-col absolute inset-y-0`}>
<aside
className={`flex flex-col flex-grow overflow-y-auto border-r py-6 px-4 overflow-auto border-[var(--frontmatter-border)]`}
>
<h2 className={`text-lg text-[var(--frontmatter-text)]`}>
{l10n.t(LocalizationKey.dashboardDataViewDataViewSelect)}
{localize(LocalizationKey.dashboardDataViewDataViewSelect)}
</h2>
<nav className={`flex-1 py-4 -mx-4`}>
<div
className={`divide-y border-t border-b divide-[var(--frontmatter-border)] border-[var(--frontmatter-border)]`}
>
{dataFiles &&
dataFiles.length > 0 &&
dataFiles.map((dataFile, idx) => (
@@ -212,30 +232,82 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
enterFrom="opacity-0"
enterTo="opacity-100">
<div className={`w-full px-4 py-2 border-b border-[var(--frontmatter-border)]`}>
{selectedData && (
<DropdownMenu>
<MenuButton
label={l10n.t(LocalizationKey.dashboardDataViewDataViewSelect)}
title={selectedData.title}
/>
<div className={`flex justify-between`}>
<div className={`flex gap-4`}>
{
selectedData && (
<DropdownMenu>
<MenuButton
label={localize(LocalizationKey.dashboardDataViewDataViewSelect)}
title={selectedData.title}
/>
<DropdownMenuContent>
{dataFiles.map((dataFile) => (
<MenuItem
key={dataFile.id}
title={dataFile.title}
value={dataFile}
isCurrent={selectedData.id === dataFile.id}
onClick={() => setSchema(dataFile)}
/>
))}
</DropdownMenuContent>
</DropdownMenu>
)}
<DropdownMenuContent>
{dataFiles.map((dataFile) => (
<MenuItem
key={dataFile.id}
title={dataFile.title}
value={dataFile}
isCurrent={selectedData.id === dataFile.id}
onClick={() => setSchema(dataFile)}
/>
))}
</DropdownMenuContent>
</DropdownMenu>
)
}
{
fileCreationFolders && fileCreationFolders.length > 0 && (
<DropdownMenu>
<MenuButton
label={localize(LocalizationKey.dashboardDataViewDataViewCreateNew)}
title={localize(LocalizationKey.dashboardDataViewDataViewSelectDataFolder)}
/>
<DropdownMenuContent>
{fileCreationFolders.map((folder) => (
<MenuItem
key={folder.id}
title={folder.id}
value={folder}
onClick={() => createDataFile(folder)}
/>
))}
</DropdownMenuContent>
</DropdownMenu>
)
}
</div>
{
selectedData && (
<div className={`flex gap-2`}>
<ActionsBarItem
className='flex items-center'
onClick={() => openFile(selectedData.file)}
title={localize(LocalizationKey.commonView)}
>
<EyeIcon className="w-4 h-4 mr-1" aria-hidden="true" />
<span>{localize(LocalizationKey.commonView)}</span>
</ActionsBarItem>
<ActionsBarItem
className='flex items-center hover:text-[var(--vscode-statusBarItem-warningBackground)]'
onClick={() => setSelectedData(null)}
title={localize(LocalizationKey.dashboardDataViewDataViewCloseSelectedDataFile)}
>
<XMarkIcon className="w-4 h-4 mr-1" aria-hidden="true" />
<span>{localize(LocalizationKey.dashboardDataViewDataViewCloseSelectedDataFile)}</span>
</ActionsBarItem>
</div>
)
}
</div>
</div>
</Transition>
<section className={`flex min-w-0 h-full ease transition-[padding] ${selectedData ? "" : "pl-64"}`}>
<section className={`flex min-w-0 h-full ease transition-[padding] ${selectedData ? "" : hasOnlyDataCreationFolders ? "" : "pl-64"}`}>
{selectedData ? (
<>
{!selectedData.singleEntry && (
@@ -243,7 +315,7 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
className={`w-1/3 py-6 px-4 flex-1 border-r overflow-auto border-[var(--frontmatter-border)]`}
>
<h2 className={`text-lg text-[var(--frontmatter-text)]`}>
{l10n.t(LocalizationKey.dashboardDataViewDataViewTitle, selectedData?.title?.toLowerCase() || '')}
{localize(LocalizationKey.dashboardDataViewDataViewTitle, selectedData?.title?.toLowerCase() || '')}
</h2>
<div className="py-4">
@@ -262,14 +334,14 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
/>
))}
</Container>
<Button className="mt-4" onClick={() => setSelectedIndex(null)}>
{l10n.t(LocalizationKey.dashboardDataViewDataViewAdd)}
<Button className="mt-4 !py-2" onClick={() => setSelectedIndex(null)}>
{localize(LocalizationKey.dashboardDataViewDataViewAdd)}
</Button>
</>
) : (
<div className={`flex flex-col items-center justify-center`}>
<p className={`text-[var(--frontmatter-text)]`}>
{l10n.t(LocalizationKey.dashboardDataViewDataViewEmpty, selectedData.title.toLowerCase())}
{localize(LocalizationKey.dashboardDataViewDataViewEmpty, selectedData.title.toLowerCase())}
</p>
</div>
)}
@@ -281,7 +353,7 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
} py-6 px-4 overflow-auto`}
>
<h2 className={`text-lg text-[var(--frontmatter-text)]`}>
{l10n.t(LocalizationKey.dashboardDataViewDataViewCreateOrModify, selectedData.title.toLowerCase())}
{localize(LocalizationKey.dashboardDataViewDataViewCreateOrModify, selectedData.title.toLowerCase())}
</h2>
{selectedData ? (
<DataForm
@@ -291,12 +363,14 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
onClear={() => setSelectedIndex(null)}
/>
) : (
<p>{l10n.t(LocalizationKey.dashboardDataViewDataViewGetStarted)}</p>
<p>{localize(LocalizationKey.dashboardDataViewDataViewGetStarted)}</p>
)}
</div>
</>
) : (
<EmptyView />
<EmptyView
folders={fileCreationFolders}
onCreate={createDataFile} />
)}
</section>
</div>
@@ -304,14 +378,14 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
<div className="w-full h-full flex items-center justify-center">
<div className={`flex flex-col items-center text-[var(--frontmatter-text)]`}>
<CircleStackIcon className="w-32 h-32" />
<p className="text-3xl mt-2">{l10n.t(LocalizationKey.dashboardDataViewDataViewNoDataFiles)}</p>
<p className="text-3xl mt-2">{localize(LocalizationKey.dashboardDataViewDataViewNoDataFiles)}</p>
<p className="text-xl mt-4">
<a
className={`text-[var(--frontmatter-link)] hover:text-[var(--frontmatter-link-hover)]`}
href={WEBSITE_LINKS.docs.dataDashboard}
title={l10n.t(LocalizationKey.dashboardDataViewDataViewGetStartedLink)}
title={localize(LocalizationKey.dashboardDataViewDataViewGetStartedLink)}
>
{l10n.t(LocalizationKey.dashboardDataViewDataViewGetStartedLink)}
{localize(LocalizationKey.dashboardDataViewDataViewGetStartedLink)}
</a>
</p>
</div>
@@ -319,6 +393,8 @@ export const DataView: React.FunctionComponent<IDataViewProps> = (
)
}
{loading && <Spinner />}
<SponsorMsg
beta={settings?.beta}
version={settings?.versionInfo}

View File

@@ -1,20 +1,56 @@
import { ExclamationCircleIcon } from '@heroicons/react/24/outline';
import * as React from 'react';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { LocalizationKey, localize } from '../../../localization';
import { DataFolder } from '../../../models';
import { DropdownMenu, DropdownMenuContent } from '../../../components/shadcn/Dropdown';
import { MenuButton, MenuItem } from '../Menu';
export interface IEmptyViewProps { }
export interface IEmptyViewProps {
folders: DataFolder[];
onCreate: (folder: DataFolder) => void;
}
export const EmptyView: React.FunctionComponent<IEmptyViewProps> = (
props: React.PropsWithChildren<IEmptyViewProps>
{ folders, onCreate }: React.PropsWithChildren<IEmptyViewProps>
) => {
return (
<div className="flex flex-col items-center justify-center w-full">
<div className="flex flex-col items-center justify-center w-full space-y-2">
<ExclamationCircleIcon className={`w-1/12 opacity-90 text-[var(--frontmatter-secondary-text)]`} />
<h2 className={`text-xl text-[var(--frontmatter-secondary-text)]`}>
{l10n.t(LocalizationKey.dashboardDataViewEmptyViewHeading)}
{
(folders && folders.length > 0) ?
localize(LocalizationKey.dashboardDataViewEmptyViewHeadingCreate) :
l10n.t(LocalizationKey.dashboardDataViewEmptyViewHeading)
}
</h2>
{
onCreate && folders && folders.length > 0 && (
<div className=''>
<DropdownMenu>
<MenuButton
label={localize(LocalizationKey.dashboardDataViewDataViewCreateNew)}
title={localize(LocalizationKey.dashboardDataViewDataViewSelectDataFolder)}
className={`text-lg`}
labelClass={`font-normal text-[var(--frontmatter-secondary-text)]`}
/>
<DropdownMenuContent>
{folders.map((folder) => (
<MenuItem
key={folder.id}
title={folder.id}
value={folder}
onClick={() => onCreate(folder)}
/>
))}
</DropdownMenuContent>
</DropdownMenu>
</div>
)
}
</div>
);
};

View File

@@ -9,7 +9,7 @@ import { LocalizationKey } from '../../../localization';
export interface ILanguageFilterProps { }
export const LanguageFilter: React.FunctionComponent<ILanguageFilterProps> = ({ }: React.PropsWithChildren<ILanguageFilterProps>) => {
export const LanguageFilter: React.FunctionComponent<ILanguageFilterProps> = () => {
const locales = useRecoilValue(LocalesAtom);
const [crntLocale, setCrntLocale] = useRecoilState(LocaleAtom);

View File

@@ -1,11 +1,10 @@
import * as React from 'react';
import { NavigationType, Page } from '../../models';
import { CommandLineIcon, PencilIcon, TrashIcon, ChevronDownIcon, XMarkIcon, EyeIcon, LanguageIcon } from '@heroicons/react/24/outline';
import { CommandLineIcon, PencilIcon, TrashIcon, ChevronDownIcon, XMarkIcon, EyeIcon, LanguageIcon, CheckIcon } from '@heroicons/react/24/outline';
import { useRecoilState, useRecoilValue } from 'recoil';
import { MultiSelectedItemsAtom, SelectedItemActionAtom, SelectedMediaFolderSelector, SettingsSelector } from '../../state';
import { MultiSelectedItemsAtom, PagedItems, SelectedItemActionAtom, SelectedMediaFolderSelector, SettingsSelector } from '../../state';
import { ActionsBarItem } from './ActionsBarItem';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { LocalizationKey, localize } from '../../../localization';
import { Alert } from '../Modals/Alert';
import { messageHandler } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
@@ -29,6 +28,7 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
const selectedFolder = useRecoilValue(SelectedMediaFolderSelector);
const settings = useRecoilValue(SettingsSelector);
const { files } = useFilesContext();
const pagedItems = useRecoilValue(PagedItems);
const viewFile = React.useCallback(() => {
if (selectedFiles.length === 1) {
@@ -66,6 +66,16 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
}
}, [selectedFiles]);
const selectAllItems = React.useCallback(() => {
const allSelected = [...selectedFiles, ...pagedItems];
setSelectedFiles(Array.from(new Set(allSelected)));
}, [selectedFiles, pagedItems]);
const hasAllItemsSelectedOnPage = React.useMemo(() => {
const selectedItemsOnPage = selectedFiles.filter((file) => pagedItems.includes(file));
return selectedItemsOnPage.length >= pagedItems.length;
}, [selectedFiles, pagedItems]);
const languageActions = React.useMemo(() => {
const actions: React.ReactNode[] = [];
@@ -87,7 +97,7 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
})
}}>
<LanguageIcon className={`mr-2 h-4 w-4`} aria-hidden={true} />
<span>{l10n.t(LocalizationKey.commonTranslate)}</span>
<span>{localize(LocalizationKey.commonTranslate)}</span>
</ActionsBarItem>
)
@@ -102,7 +112,7 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
className='flex items-center text-[var(--vscode-tab-inactiveForeground)] hover:text-[var(--vscode-tab-activeForeground)]'
>
<LanguageIcon className="mr-2 h-4 w-4" aria-hidden={true} />
<span>{l10n.t(LocalizationKey.commonLanguages)}</span>
<span>{localize(LocalizationKey.commonLanguages)}</span>
<ChevronDownIcon className="ml-2 h-4 w-4" aria-hidden={true} />
</DropdownMenuTrigger>
@@ -158,7 +168,7 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
disabled={selectedFiles.length === 0}
>
<CommandLineIcon className="mr-2 h-4 w-4" aria-hidden={true} />
<span>{l10n.t(LocalizationKey.commonScripts)}</span>
<span>{localize(LocalizationKey.commonScripts)}</span>
<ChevronDownIcon className="ml-2 h-4 w-4" aria-hidden={true} />
</DropdownMenuTrigger>
@@ -192,9 +202,10 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
<ActionsBarItem
disabled={selectedFiles.length === 0 || selectedFiles.length > 1}
onClick={viewFile}
title={localize(LocalizationKey.commonView)}
>
<EyeIcon className="w-4 h-4 mr-2" aria-hidden="true" />
<span>{l10n.t(LocalizationKey.commonView)}</span>
<span>{localize(LocalizationKey.commonView)}</span>
</ActionsBarItem>
{
@@ -205,9 +216,10 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
messageHandler.send(DashboardMessage.rename, selectedFiles[0]);
setSelectedFiles([]);
}}
title={localize(LocalizationKey.commonRename)}
>
<RenameIcon className="w-4 h-4 mr-2" aria-hidden="true" />
<span>{l10n.t(LocalizationKey.commonRename)}</span>
<span>{localize(LocalizationKey.commonRename)}</span>
</ActionsBarItem>
)
}
@@ -221,9 +233,10 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
path: selectedFiles[0],
action: 'edit'
})}
title={localize(LocalizationKey.commonEdit)}
>
<PencilIcon className="w-4 h-4 mr-2" aria-hidden="true" />
<span>{l10n.t(LocalizationKey.commonEdit)}</span>
<span>{localize(LocalizationKey.commonEdit)}</span>
</ActionsBarItem>
</>
)
@@ -237,36 +250,51 @@ export const ActionsBar: React.FunctionComponent<IActionsBarProps> = ({
className='hover:text-[var(--vscode-statusBarItem-errorBackground)]'
disabled={selectedFiles.length === 0}
onClick={() => setShowAlert(true)}
title={localize(LocalizationKey.commonDelete)}
>
<TrashIcon className="w-4 h-4 mr-2" aria-hidden="true" />
<span>{l10n.t(LocalizationKey.commonDelete)}</span>
<span>{localize(LocalizationKey.commonDelete)}</span>
</ActionsBarItem>
</div>
{
selectedFiles.length > 0 && (
<button
type="button"
className='flex items-center hover:text-[var(--vscode-statusBarItem-warningBackground)]'
onClick={() => setSelectedFiles([])}
>
<XMarkIcon className="w-4 h-4 mr-1" aria-hidden="true" />
<span>{l10n.t(LocalizationKey.dashboardHeaderActionsBarItemsSelected, selectedFiles.length)}</span>
</button>
)
}
</div>
<div className='flex gap-4'>
{
selectedFiles.length > 0 && (
<ActionsBarItem
className='flex items-center hover:text-[var(--vscode-statusBarItem-warningBackground)]'
onClick={() => setSelectedFiles([])}
title={localize(LocalizationKey.dashboardHeaderActionsBarItemsSelected, selectedFiles.length)}
>
<XMarkIcon className="w-4 h-4 mr-1" aria-hidden="true" />
<span>{localize(LocalizationKey.dashboardHeaderActionsBarItemsSelected, selectedFiles.length)}</span>
</ActionsBarItem>
)
}
<ActionsBarItem
disabled={hasAllItemsSelectedOnPage}
onClick={selectAllItems}
title={localize(LocalizationKey.dashboardHeaderActionsBarSelectAll)}
>
<div className='w-4 h-4 inline-flex items-center justify-center border border-[var(--vscode-sideBar-foreground)] group-hover:border-[var(--vscode-statusBarItem-warningBackground)] rounded mr-1'>
<CheckIcon className="w-3 h-3" aria-hidden="true" />
</div>
<span>{localize(LocalizationKey.dashboardHeaderActionsBarSelectAll)}</span>
</ActionsBarItem>
</div>
</div >
{showAlert && (
<Alert
title={`${l10n.t(LocalizationKey.dashboardHeaderActionsBarAlertDeleteTitle)}`}
description={l10n.t(LocalizationKey.dashboardHeaderActionsBarAlertDeleteDescription)}
okBtnText={l10n.t(LocalizationKey.commonDelete)}
cancelBtnText={l10n.t(LocalizationKey.commonCancel)}
title={`${localize(LocalizationKey.dashboardHeaderActionsBarAlertDeleteTitle)}`}
description={localize(LocalizationKey.dashboardHeaderActionsBarAlertDeleteDescription)}
okBtnText={localize(LocalizationKey.commonDelete)}
cancelBtnText={localize(LocalizationKey.commonCancel)}
dismiss={() => setShowAlert(false)}
trigger={onDeleteConfirm}
/>
)}
)
}
</>
);
};

View File

@@ -2,6 +2,7 @@ import * as React from 'react';
import { cn } from '../../../utils/cn';
export interface IActionsBarItemProps {
title?: string;
className?: string;
disabled?: boolean;
onClick?: () => void;
@@ -11,11 +12,13 @@ export const ActionsBarItem: React.FunctionComponent<IActionsBarItemProps> = ({
children,
className,
disabled,
onClick
onClick,
title
}: React.PropsWithChildren<IActionsBarItemProps>) => {
return (
<button
type="button"
title={title || ''}
className={cn(`flex items-center text-[var(--vscode-tab-inactiveForeground)] hover:text-[var(--vscode-tab-activeForeground)] disabled:opacity-50 disabled:hover:text-[var(--vscode-tab-inactiveForeground)]`, className)}
onClick={onClick}
disabled={disabled}

View File

@@ -0,0 +1,38 @@
import * as React from 'react';
import { Messenger } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { Checkbox as VSCodeCheckbox } from 'vscrui';
export interface IBooleanOptionProps {
value: boolean | undefined | null;
name: string;
label: string;
}
export const BooleanOption: React.FunctionComponent<IBooleanOptionProps> = ({
value,
name,
label
}: React.PropsWithChildren<IBooleanOptionProps>) => {
const [isChecked, setIsChecked] = React.useState(false);
const onChange = React.useCallback((newValue: boolean) => {
setIsChecked(newValue);
Messenger.send(DashboardMessage.updateSetting, {
name: name,
value: newValue
});
}, [name]);
React.useEffect(() => {
setIsChecked(!!value);
}, [value]);
return (
<VSCodeCheckbox
onChange={onChange}
checked={isChecked}>
{label}
</VSCodeCheckbox>
);
};

View File

@@ -21,16 +21,16 @@ import { useEffect, useMemo } from 'react';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
export const guardRecoilDefaultValue = (candidate: any): candidate is DefaultValue => {
if (candidate instanceof DefaultValue) return true;
export const guardRecoilDefaultValue = (candidate: unknown): candidate is DefaultValue => {
if (candidate instanceof DefaultValue) {
return true;
}
return false;
};
export interface IClearFiltersProps { }
export const ClearFilters: React.FunctionComponent<IClearFiltersProps> = (
_: React.PropsWithChildren<IClearFiltersProps>
) => {
export const ClearFilters: React.FunctionComponent<IClearFiltersProps> = () => {
const [show, setShow] = React.useState(false);
const folder = useRecoilValue(FolderSelector);
@@ -75,7 +75,9 @@ export const ClearFilters: React.FunctionComponent<IClearFiltersProps> = (
}
}, [folder, tag, category, locale, hasCustomFilters]);
if (!show) return null;
if (!show) {
return null;
}
return (
<button

View File

@@ -10,7 +10,7 @@ import { LanguageFilter } from '../Filters/LanguageFilter';
export interface IFiltersProps { }
export const Filters: React.FunctionComponent<IFiltersProps> = (_: React.PropsWithChildren<IFiltersProps>) => {
export const Filters: React.FunctionComponent<IFiltersProps> = () => {
const [crntFilters, setCrntFilters] = useRecoilState(FiltersAtom);
const [crntTag, setCrntTag] = useRecoilState(TagAtom);
const [crntCategory, setCrntCategory] = useRecoilState(CategoryAtom);
@@ -24,19 +24,37 @@ export const Filters: React.FunctionComponent<IFiltersProps> = (_: React.PropsWi
return otherFilters?.map((filter) => {
const filterName = typeof filter === "string" ? filter : filter.name;
const filterTitle = typeof filter === "string" ? firstToUpper(filter) : filter.title;
const values = filterValues?.[filterName];
let values = filterValues?.[filterName];
if (!values || values.length === 0) {
return null;
}
// Get all the unique values
const individualValues = new Set<string>();
values.forEach((value) => {
if (value.length === 0) {
return;
}
if (Array.isArray(value)) {
value.forEach((v) => individualValues.add(v));
}
if (typeof value === "string") {
individualValues.add(value);
}
});
values = Array.from(individualValues);
return (
<Filter
key={filterName}
label={filterTitle}
activeItem={crntFilters[filterName]}
items={values}
items={values as string[]}
onClick={(value) => setCrntFilters((prev) => {
let clone = Object.assign({}, prev);
const clone = Object.assign({}, prev);
if (!clone[filterName] && value) {
clone[filterName] = value;
} else {

View File

@@ -10,7 +10,7 @@ export interface IFoldersFilterProps { }
export const FoldersFilter: React.FunctionComponent<
IFoldersFilterProps
> = ({ }: React.PropsWithChildren<IFoldersFilterProps>) => {
> = () => {
const DEFAULT_TYPE = l10n.t(LocalizationKey.dashboardHeaderFoldersDefault);
const [crntFolder, setCrntFolder] = useRecoilState(FolderAtom);
const settings = useRecoilValue(SettingsSelector);

View File

@@ -1,39 +1,44 @@
import * as React from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { GroupOption } from '../../constants/GroupOption';
import { AllPagesAtom, GroupingAtom } from '../../state';
import { AllPagesAtom, GroupingAtom, SettingsAtom } from '../../state';
import { MenuButton, MenuItem } from '../Menu';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { LocalizationKey, localize } from '../../../localization';
import { DropdownMenu, DropdownMenuContent } from '../../../components/shadcn/Dropdown';
export interface IGroupingProps { }
export const Grouping: React.FunctionComponent<
IGroupingProps
> = ({ }: React.PropsWithChildren<IGroupingProps>) => {
> = () => {
const settings = useRecoilValue(SettingsAtom);
const [group, setGroup] = useRecoilState(GroupingAtom);
const pages = useRecoilValue(AllPagesAtom);
const GROUP_OPTIONS = React.useMemo(() => {
let options: { name: string, id: GroupOption }[] = [];
const options: { name: string, id?: GroupOption | string }[] = [];
if (pages.length > 0) {
if (settings?.grouping) {
const groups = settings.grouping.map((g) => ({ name: g.title, id: g.name }));
options.push(...groups);
}
if (pages.some((x) => x.fmYear)) {
options.push({ name: l10n.t(LocalizationKey.dashboardHeaderGroupingOptionYear), id: GroupOption.Year })
options.push({ name: localize(LocalizationKey.dashboardHeaderGroupingOptionYear), id: GroupOption.Year })
}
if (pages.some((x) => x.fmDraft)) {
options.push({ name: l10n.t(LocalizationKey.dashboardHeaderGroupingOptionDraft), id: GroupOption.Draft })
options.push({ name: localize(LocalizationKey.dashboardHeaderGroupingOptionDraft), id: GroupOption.Draft })
}
}
if (options.length > 0) {
options.unshift({ name: l10n.t(LocalizationKey.dashboardHeaderGroupingOptionNone), id: GroupOption.none })
options.unshift({ name: localize(LocalizationKey.dashboardHeaderGroupingOptionNone), id: GroupOption.none })
}
return options;
}, [pages])
}, [pages, settings?.grouping])
const crntGroup = GROUP_OPTIONS.find((x) => x.id === group);
@@ -43,7 +48,7 @@ export const Grouping: React.FunctionComponent<
return (
<DropdownMenu>
<MenuButton label={l10n.t(LocalizationKey.dashboardHeaderGroupingMenuButtonLabel)} title={crntGroup?.name || ''} />
<MenuButton label={localize(LocalizationKey.dashboardHeaderGroupingMenuButtonLabel)} title={crntGroup?.name || ''} />
<DropdownMenuContent>
{GROUP_OPTIONS.map((option) => (

View File

@@ -14,7 +14,7 @@ import { ChoiceButton } from '../Common/ChoiceButton';
import { MediaHeaderBottom } from '../Media/MediaHeaderBottom';
import { Tabs } from './Tabs';
import { CustomScript } from '../../../models';
import { ArrowTopRightOnSquareIcon, BoltIcon, PlusIcon } from '@heroicons/react/24/outline';
import { ArrowTopRightOnSquareIcon, BoltIcon, BookOpenIcon, PlusIcon } from '@heroicons/react/24/outline';
import { HeartIcon } from '@heroicons/react/24/solid';
import { useLocation, useNavigate } from 'react-router-dom';
import { routePaths } from '../..';
@@ -29,7 +29,7 @@ import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { SettingsLink } from '../SettingsView/SettingsLink';
import { Link } from '../Common/Link';
import { SPONSOR_LINK } from '../../../constants';
import { COMMAND_NAME, GeneralCommands, SPONSOR_LINK } from '../../../constants';
import { Filters } from './Filters';
import { ActionsBar } from './ActionsBar';
import { RefreshDashboardData } from './RefreshDashboardData';
@@ -157,6 +157,16 @@ export const Header: React.FunctionComponent<IHeaderProps> = ({
)
}
<button
className="inline-flex items-center hover:text-[var(--vscode-textLink-activeForeground)]"
title={l10n.t(LocalizationKey.commonDocs)}
onClick={() => Messenger.send(GeneralCommands.toVSCode.runCommand, {
command: COMMAND_NAME.docs
})}>
<span className='sr-only'>{l10n.t(LocalizationKey.commonDocs)}</span>
<BookOpenIcon className='w-4 h-4' aria-hidden="true" />
</button>
<SettingsLink onNavigate={updateView} />
</div>
</div>

View File

@@ -37,9 +37,7 @@ const NavigationItem: React.FunctionComponent<INavigationItemProps> = ({
)
};
export const Navigation: React.FunctionComponent<INavigationProps> = ({
}: React.PropsWithChildren<INavigationProps>) => {
export const Navigation: React.FunctionComponent<INavigationProps> = () => {
const [crntTab, setCrntTab] = useRecoilState(TabAtom);
const tabInfo = useRecoilValue(TabInfoAtom);
const settings = useRecoilValue(SettingsAtom);

View File

@@ -23,15 +23,28 @@ export const Pagination: React.FunctionComponent<IPaginationProps> = ({
totalMedia
);
const getButtons = useCallback((): number[] => {
const buttons = useMemo((): JSX.Element[] => {
const maxButtons = 5;
const buttons: number[] = [];
const buttons: JSX.Element[] = [];
const start = page - maxButtons;
const end = page + maxButtons;
for (let i = start; i < end; i++) {
if (i >= 0 && i <= totalPagesNr) {
buttons.push(i);
buttons.push(
<button
key={i}
disabled={i === page}
onClick={() => {
setPage(i);
}}
className={`max-h-8 rounded ${page === i
? `px-2 bg-[var(--vscode-list-activeSelectionBackground)] text-[var(--vscode-list-activeSelectionForeground)]`
: `text-[var(--vscode-editor-foreground)] hover:text-[var(--vscode-list-activeSelectionForeground)]`}`}
>
{i + 1}
</button>
);
}
}
return buttons;
@@ -67,20 +80,7 @@ export const Pagination: React.FunctionComponent<IPaginationProps> = ({
}}
/>
{getButtons().map((button) => (
<button
key={button}
disabled={button === page}
onClick={() => {
setPage(button);
}}
className={`max-h-8 rounded ${page === button
? `px-2 bg-[var(--vscode-list-activeSelectionBackground)] text-[var(--vscode-list-activeSelectionForeground)]`
: `text-[var(--vscode-editor-foreground)] hover:text-[var(--vscode-list-activeSelectionForeground)]`}`}
>
{button + 1}
</button>
))}
{buttons}
<PaginationButton
title={l10n.t(LocalizationKey.dashboardHeaderPaginationNext)}

View File

@@ -21,9 +21,7 @@ import { ArrowClockwiseIcon } from '../../../components/icons/ArrowClockwiseIcon
export interface IRefreshDashboardDataProps { }
export const RefreshDashboardData: React.FunctionComponent<IRefreshDashboardDataProps> = (
{ }: React.PropsWithChildren<IRefreshDashboardDataProps>
) => {
export const RefreshDashboardData: React.FunctionComponent<IRefreshDashboardDataProps> = () => {
const view = useRecoilValue(DashboardViewAtom);
const [, setLoading] = useRecoilState(LoadingAtom);
const resetSearch = useResetRecoilState(SearchAtom);

View File

@@ -165,7 +165,7 @@ export const Sorting: React.FunctionComponent<ISortingProps> = ({
}
}
let sort = allOptions.find((x) => x.id === crntSortingOption?.id) || sortOptions[0];
const sort = allOptions.find((x) => x.id === crntSortingOption?.id) || sortOptions[0];
setCrntSort(sort);
};

View File

@@ -5,8 +5,7 @@ import { DashboardMessage } from '../../DashboardMessage';
import { SETTING_DASHBOARD_OPENONSTART } from '../../../constants';
import * as l10n from "@vscode/l10n"
import { LocalizationKey } from '../../../localization';
import { VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
import { Checkbox as VSCodeCheckbox } from 'vscrui';
export interface IStartupProps {
settings: Settings | null;
@@ -31,7 +30,7 @@ export const Startup: React.FunctionComponent<IStartupProps> = ({
return (
<VSCodeCheckbox
onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange(e.target.checked)}
onChange={onChange}
checked={isChecked}>
{l10n.t(LocalizationKey.dashboardHeaderStartupLabel)}
</VSCodeCheckbox>

View File

@@ -9,6 +9,7 @@ import { Tab } from './Tab';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { PageIcon } from '../../../panelWebView/components/Icons';
import { DEFAULT_DASHBOARD_FEATURE_FLAGS } from '../../../constants/DefaultFeatureFlags';
export interface ITabsProps {
onNavigate: (navigationType: NavigationType) => void;
@@ -19,12 +20,6 @@ export const Tabs: React.FunctionComponent<ITabsProps> = ({
}: React.PropsWithChildren<ITabsProps>) => {
const mode = useRecoilValue(ModeAtom);
const allDashboardVIews = [
FEATURE_FLAG.dashboard.snippets.view,
FEATURE_FLAG.dashboard.data.view,
FEATURE_FLAG.dashboard.taxonomy.view
];
return (
<ul
className="flex items-center justify-start h-full space-x-4"
@@ -43,7 +38,7 @@ export const Tabs: React.FunctionComponent<ITabsProps> = ({
<span>{l10n.t(LocalizationKey.dashboardHeaderTabsMedia)}</span>
</Tab>
</li>
<FeatureFlag features={mode?.features || [...allDashboardVIews]} flag={FEATURE_FLAG.dashboard.snippets.view}>
<FeatureFlag features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS} flag={FEATURE_FLAG.dashboard.snippets.view}>
<li role="presentation">
<Tab navigationType={NavigationType.Snippets} onNavigate={onNavigate}>
<ScissorsIcon className={`h-4 w-auto mr-2`} />
@@ -51,7 +46,7 @@ export const Tabs: React.FunctionComponent<ITabsProps> = ({
</Tab>
</li>
</FeatureFlag>
<FeatureFlag features={mode?.features || [...allDashboardVIews]} flag={FEATURE_FLAG.dashboard.data.view}>
<FeatureFlag features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS} flag={FEATURE_FLAG.dashboard.data.view}>
<li role="presentation">
<Tab navigationType={NavigationType.Data} onNavigate={onNavigate}>
<CircleStackIcon className={`h-4 w-auto mr-2`} />
@@ -59,7 +54,7 @@ export const Tabs: React.FunctionComponent<ITabsProps> = ({
</Tab>
</li>
</FeatureFlag>
<FeatureFlag features={mode?.features || [...allDashboardVIews]} flag={FEATURE_FLAG.dashboard.taxonomy.view}>
<FeatureFlag features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS} flag={FEATURE_FLAG.dashboard.taxonomy.view}>
<li role="presentation">
<Tab navigationType={NavigationType.Taxonomy} onNavigate={onNavigate}>
<TagIcon className={`h-4 w-auto mr-2`} />

View File

@@ -33,6 +33,9 @@ export const CustomActions: React.FunctionComponent<ICustomActionsProps> = ({
));
}, [scripts]);
if (!customActions.length) {
return null;
}
if (showTrigger) {
return (

View File

@@ -91,8 +91,9 @@ export const FolderCreation: React.FunctionComponent<IFolderCreationProps> = (
if (scripts.length > 0) {
return (
<div className="flex flex-1 justify-start">
<div className="flex flex-1 justify-start space-x-2">
{renderPostAssetsButton}
<ChoiceButton
title={l10n.t(LocalizationKey.dashboardMediaFolderCreationFolderCreate)}
choices={scripts.map((s) => ({
@@ -103,6 +104,8 @@ export const FolderCreation: React.FunctionComponent<IFolderCreationProps> = (
onClick={onFolderCreation}
disabled={!settings?.initialized}
/>
<RefreshDashboardData />
</div>
);
}

View File

@@ -1,9 +1,14 @@
import { FolderIcon } from '@heroicons/react/24/solid';
import { FolderIcon, PencilIcon, TrashIcon } from '@heroicons/react/24/solid';
import { basename, join } from 'path';
import * as React from 'react';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { LocalizationKey, localize } from '../../../localization';
import useMediaFolder from '../../hooks/useMediaFolder';
import { QuickAction } from '../Menu';
import { messageHandler } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { useState } from 'react';
import { Alert } from '../Modals/Alert';
import { parseWinPath } from '../../../helpers/parseWinPath';
export interface IFolderItemProps {
folder: string;
@@ -17,6 +22,7 @@ export const FolderItem: React.FunctionComponent<IFolderItemProps> = ({
staticFolder
}: React.PropsWithChildren<IFolderItemProps>) => {
const { updateFolder } = useMediaFolder();
const [showAlert, setShowAlert] = useState(false);
const relFolderPath = wsFolder ? folder.replace(wsFolder, '') : folder;
@@ -25,28 +31,73 @@ export const FolderItem: React.FunctionComponent<IFolderItemProps> = ({
[relFolderPath, staticFolder]
);
return (
<li
className={`group relative hover:bg-[var(--vscode-list-hoverBackground)] text-[var(--vscode-editor-foreground)] hover:text-[var(--vscode-list-activeSelectionForeground)]`}
>
<button
title={isContentFolder ? l10n.t(LocalizationKey.dashboardMediaFolderItemContentDirectory) : l10n.t(LocalizationKey.dashboardMediaFolderItemPublicDirectory)}
className={`p-4 w-full flex flex-row items-center h-full`}
onClick={() => updateFolder(folder)}
>
<div className="relative mr-4">
<FolderIcon className={`h-12 w-12`} />
{isContentFolder && (
<span className={`font-extrabold absolute bottom-3 left-1/2 transform -translate-x-1/2 text-[var(--frontmatter-text)]`}>
C
</span>
)}
</div>
const updateFolderName = React.useCallback(() => {
messageHandler.send(DashboardMessage.updateMediaFolder, { folder, wsFolder, staticFolder })
}, []);
<p className="text-sm font-bold pointer-events-none flex items-center text-left overflow-hidden break-words">
{basename(relFolderPath)}
</p>
</button>
</li>
const onDelete = React.useCallback(() => {
setShowAlert(true);
}, []);
const confirmDeletion = React.useCallback(() => {
messageHandler.send(DashboardMessage.deleteMediaFolder, { folder });
setShowAlert(false);
}, [folder]);
return (
<>
<li
className={`flex flex-col group relative text-[var(--vscode-sideBarTitle-foreground)] hover:text-[var(--vscode-list-activeSelectionForeground)] shadow-md hover:shadow-xl dark:shadow-none bg-[var(--vscode-sideBar-background)] hover:bg-[var(--vscode-list-hoverBackground)] border border-[var(--frontmatter-border)] rounded`}
>
<button
title={isContentFolder ? localize(LocalizationKey.dashboardMediaFolderItemContentDirectory) : localize(LocalizationKey.dashboardMediaFolderItemPublicDirectory)}
className={`p-4 w-full flex flex-row items-center h-full`}
onClick={() => updateFolder(folder)}
>
<div className="relative mr-4">
<FolderIcon className={`h-12 w-12`} />
{isContentFolder && (
<span className={`font-extrabold absolute bottom-3 left-1/2 transform -translate-x-1/2 text-[var(--frontmatter-text)]`}>
C
</span>
)}
</div>
<p className="text-sm font-bold pointer-events-none flex items-center text-left overflow-hidden break-words">
{basename(relFolderPath)}
</p>
</button>
{!isContentFolder && (
<div className={`py-2 w-full flex items-center justify-evenly border-t border-t-[var(--frontmatter-border)] bg-[var(--frontmatter-sideBar-background)] group-hover:bg-[var(--vscode-list-hoverBackground)]`}>
<QuickAction
title={localize(LocalizationKey.commonEdit)}
className={`text-[var(--frontmatter-secondary-text)]`}
onClick={updateFolderName}>
<PencilIcon className={`w-4 h-4`} aria-hidden="true" />
<span className='sr-only'>{localize(LocalizationKey.dashboardMediaItemMenuItemView)}</span>
</QuickAction>
<QuickAction
title={localize(LocalizationKey.dashboardMediaItemQuickActionDelete)}
className={`text-[var(--frontmatter-secondary-text)] hover:text-[var(--vscode-statusBarItem-errorBackground)]`}
onClick={onDelete}>
<TrashIcon className={`w-4 h-4`} aria-hidden="true" />
</QuickAction>
</div>
)}
</li>
{showAlert && (
<Alert
title={`${localize(LocalizationKey.commonDelete)}: ${basename(parseWinPath(folder) || '')}`}
description={localize(LocalizationKey.dashboardMediaFolderItemDeleteDescription, folder)}
okBtnText={localize(LocalizationKey.commonDelete)}
cancelBtnText={localize(LocalizationKey.commonCancel)}
dismiss={() => setShowAlert(false)}
trigger={confirmDeletion}
/>
)}
</>
);
};

View File

@@ -1,7 +1,6 @@
import * as React from 'react';
import * as l10n from '@vscode/l10n';
import { QuickAction } from '../Menu';
import { LocalizationKey } from '../../../localization';
import { LocalizationKey, localize } from '../../../localization';
import { ClipboardIcon, CodeBracketIcon, EyeIcon, PencilIcon, PlusIcon, TrashIcon } from '@heroicons/react/24/solid';
import { useRecoilState } from 'recoil';
import { SelectedItemActionAtom } from '../../state';
@@ -36,25 +35,25 @@ export const FooterActions: React.FunctionComponent<IFooterActionsProps> = ({
return (
<div className={`py-2 w-full flex items-center justify-evenly border-t border-t-[var(--frontmatter-border)] bg-[var(--frontmatter-sideBar-background)] group-hover:bg-[var(--vscode-list-hoverBackground)]`}>
<QuickAction
title={l10n.t(LocalizationKey.dashboardMediaItemMenuItemView)}
title={localize(LocalizationKey.dashboardMediaItemMenuItemView)}
className={`text-[var(--frontmatter-secondary-text)]`}
onClick={() => setSelectedItemAction({
path: media.fsPath,
action: 'view'
})}>
<EyeIcon className={`w-4 h-4`} aria-hidden="true" />
<span className='sr-only'>{l10n.t(LocalizationKey.dashboardMediaItemMenuItemView)}</span>
<span className='sr-only'>{localize(LocalizationKey.dashboardMediaItemMenuItemView)}</span>
</QuickAction>
<QuickAction
title={l10n.t(LocalizationKey.dashboardMediaItemMenuItemEditMetadata)}
title={localize(LocalizationKey.dashboardMediaItemMenuItemEditMetadata)}
className={`text-[var(--frontmatter-secondary-text)]`}
onClick={() => setSelectedItemAction({
path: media.fsPath,
action: 'edit'
})}>
<PencilIcon className={`w-4 h-4`} aria-hidden="true" />
<span className='sr-only'>{l10n.t(LocalizationKey.dashboardMediaItemMenuItemEditMetadata)}</span>
<span className='sr-only'>{localize(LocalizationKey.dashboardMediaItemMenuItemEditMetadata)}</span>
</QuickAction>
{viewData?.filePath ? (
@@ -62,8 +61,8 @@ export const FooterActions: React.FunctionComponent<IFooterActionsProps> = ({
<QuickAction
title={
viewData.metadataInsert && viewData.fieldName
? l10n.t(LocalizationKey.dashboardMediaItemQuickActionInsertField, viewData.fieldName)
: l10n.t(LocalizationKey.dashboardMediaItemQuickActionInsertMarkdown)
? localize(LocalizationKey.dashboardMediaItemQuickActionInsertField, viewData.fieldName)
: localize(LocalizationKey.dashboardMediaItemQuickActionInsertMarkdown)
}
className={`text-[var(--frontmatter-secondary-text)]`}
onClick={insertIntoArticle}
@@ -73,7 +72,7 @@ export const FooterActions: React.FunctionComponent<IFooterActionsProps> = ({
{viewData?.position && snippets.length > 0 && (
<QuickAction
title={l10n.t(LocalizationKey.commonInsertSnippet)}
title={localize(LocalizationKey.commonInsertSnippet)}
className={`text-[var(--frontmatter-secondary-text)]`}
onClick={insertSnippet}>
<CodeBracketIcon className={`w-4 h-4`} aria-hidden="true" />
@@ -85,7 +84,7 @@ export const FooterActions: React.FunctionComponent<IFooterActionsProps> = ({
{
relPath && (
<QuickAction
title={l10n.t(LocalizationKey.dashboardMediaItemQuickActionCopyPath)}
title={localize(LocalizationKey.dashboardMediaItemQuickActionCopyPath)}
className={`text-[var(--frontmatter-secondary-text)]`}
onClick={() => copyToClipboard(parseWinPath(relPath) || '')}>
<ClipboardIcon className={`w-4 h-4`} aria-hidden="true" />
@@ -101,7 +100,7 @@ export const FooterActions: React.FunctionComponent<IFooterActionsProps> = ({
showTrigger />
<QuickAction
title={l10n.t(LocalizationKey.dashboardMediaItemQuickActionDelete)}
title={localize(LocalizationKey.dashboardMediaItemQuickActionDelete)}
className={`text-[var(--frontmatter-secondary-text)] hover:text-[var(--vscode-statusBarItem-errorBackground)]`}
onClick={onDelete}>
<TrashIcon className={`w-4 h-4`} aria-hidden="true" />

View File

@@ -7,7 +7,7 @@ import {
PlusIcon,
VideoCameraIcon,
} from '@heroicons/react/24/outline';
import { basename } from 'path';
import { basename, parse } from 'path';
import * as React from 'react';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
@@ -55,8 +55,17 @@ export const Item: React.FunctionComponent<IItemProps> = ({
const { mediaFolder, mediaDetails, isAudio, isImage, isVideo } = useMediaInfo(media);
const relPath = useMemo(() => {
if (viewData?.data?.pageBundle && viewData?.data?.filePath) {
const articlePath = viewData?.data?.filePath;
const articleDir = parse(parseWinPath(articlePath)).dir;
const mediaPath = parseWinPath(media.fsPath);
if (mediaPath.startsWith(articleDir)) {
return getRelPath(media.fsPath, undefined, articleDir);
}
}
return getRelPath(media.fsPath, settings?.staticFolder, settings?.wsFolder);
}, [media.fsPath, settings?.staticFolder, settings?.wsFolder]);
}, [media.fsPath, settings?.staticFolder, settings?.wsFolder, viewData?.data?.pageBundle, viewData?.data?.filePath]);
const hasViewData = useMemo(() => {
return viewData?.data?.filePath !== undefined;

View File

@@ -1,12 +1,14 @@
import { Messenger } from '@estruyf/vscode/dist/client';
import { ArrowUpTrayIcon } from '@heroicons/react/24/outline';
import * as React from 'react';
import { useRecoilValue } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import {
LoadingAtom,
MediaFoldersAtom,
PagedItems,
SelectedMediaFolderAtom,
SettingsSelector,
SortingAtom,
ViewDataSelector
} from '../../state';
import { Spinner } from '../Common/Spinner';
@@ -20,7 +22,7 @@ import { DashboardMessage } from '../../DashboardMessage';
import { FrontMatterIcon } from '../../../panelWebView/components/Icons/FrontMatterIcon';
import { FolderItem } from './FolderItem';
import useMedia from '../../hooks/useMedia';
import { GeneralCommands, STATIC_FOLDER_PLACEHOLDER, TelemetryEvent } from '../../../constants';
import { STATIC_FOLDER_PLACEHOLDER, } from '../../../constants';
import { PageLayout } from '../Layout/PageLayout';
import { parseWinPath } from '../../../helpers/parseWinPath';
import { basename, extname, join } from 'path';
@@ -29,18 +31,19 @@ import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { MediaItemPanel } from './MediaItemPanel';
import { FilesProvider } from '../../providers/FilesProvider';
import { SortOption } from '../../constants/SortOption';
export interface IMediaProps { }
export const Media: React.FunctionComponent<IMediaProps> = (
_: React.PropsWithChildren<IMediaProps>
) => {
export const Media: React.FunctionComponent<IMediaProps> = () => {
const { media } = useMedia();
const settings = useRecoilValue(SettingsSelector);
const viewData = useRecoilValue(ViewDataSelector);
const selectedFolder = useRecoilValue(SelectedMediaFolderAtom);
const folders = useRecoilValue(MediaFoldersAtom);
const loading = useRecoilValue(LoadingAtom);
const crntSorting = useRecoilValue(SortingAtom);
const [, setPagedItems] = useRecoilState(PagedItems);
const currentStaticFolder = useMemo(() => {
if (settings?.staticFolder) {
@@ -65,7 +68,7 @@ export const Media: React.FunctionComponent<IMediaProps> = (
return [];
}
let groupedFolders = [];
const groupedFolders = [];
for (const cFolder of settings?.contentFolders || []) {
const foldersPath = parseWinPath(cFolder.path);
@@ -83,11 +86,18 @@ export const Media: React.FunctionComponent<IMediaProps> = (
currentStaticFolder &&
settings?.staticFolder !== STATIC_FOLDER_PLACEHOLDER.hexo.placeholder
) {
return folders.filter((f) => parseWinPath(f).includes(currentStaticFolder));
const allFolders = folders.filter((f) => parseWinPath(f).includes(currentStaticFolder));
if (crntSorting && crntSorting.id === SortOption.FileNameAsc) {
return allFolders.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
} else if (crntSorting && crntSorting.id === SortOption.FileNameDesc) {
return allFolders.sort((a, b) => b.localeCompare(a, undefined, { numeric: true }));
} else {
return allFolders;
}
}
return undefined;
}, [folders, viewData, currentStaticFolder, settings?.staticFolder]);
}, [folders, viewData, currentStaticFolder, settings?.staticFolder, crntSorting]);
const allMedia = useMemo(() => {
let mediaFiles: MediaInfo[] = Object.assign([], media);
@@ -126,6 +136,7 @@ export const Media: React.FunctionComponent<IMediaProps> = (
});
}
setPagedItems(mediaFiles.map((m) => m.fsPath));
return mediaFiles;
}, [media, viewData, currentStaticFolder, settings?.staticFolder]);
@@ -151,15 +162,6 @@ export const Media: React.FunctionComponent<IMediaProps> = (
useEffect(() => {
Messenger.send(DashboardMessage.setTitle, l10n.t(LocalizationKey.dashboardHeaderTabsMedia));
Messenger.send(DashboardMessage.sendTelemetry, {
event: TelemetryEvent.webviewMediaView
});
Messenger.send(GeneralCommands.toVSCode.logging.info, {
message: `Media view loaded`,
location: 'DASHBOARD'
});
}, []);
const { getRootProps, isDragActive } = useDropzone({

View File

@@ -23,7 +23,7 @@ export interface IMediaHeaderTopProps { }
export const MediaHeaderTop: React.FunctionComponent<
IMediaHeaderTopProps
> = ({ }: React.PropsWithChildren<IMediaHeaderTopProps>) => {
> = () => {
const [lastUpdated, setLastUpdated] = React.useState<string | null>(null);
const selectedFolder = useRecoilValue(SelectedMediaFolderSelector);
const crntSorting = useRecoilValue(SortingSelector);

View File

@@ -1,26 +1,33 @@
import { ChevronDownIcon } from '@heroicons/react/24/solid';
import * as React from 'react';
import { DropdownMenuTrigger } from '../../../components/shadcn/Dropdown';
import { cn } from '../../../utils/cn';
export interface IMenuButtonProps {
label: string | JSX.Element;
title: string;
disabled?: boolean;
className?: string;
labelClass?: string;
buttonClass?: string;
}
export const MenuButton: React.FunctionComponent<IMenuButtonProps> = ({
label,
title,
disabled
disabled,
className,
labelClass,
buttonClass,
}: React.PropsWithChildren<IMenuButtonProps>) => {
return (
<div className={`group flex items-center shrink-0 ${disabled ? 'opacity-50' : ''}`}>
<div className={`mr-2 font-medium flex items-center text-[var(--vscode-tab-inactiveForeground)]`}>
<div className={cn(`group flex items-center shrink-0 ${disabled ? 'opacity-50' : ''} ${className || ""}`)}>
<div className={cn(`mr-2 font-medium flex items-center text-[var(--vscode-tab-inactiveForeground)] ${labelClass || ""}`)}>
{label}:
</div>
<DropdownMenuTrigger
className='text-[var(--vscode-textLink-foreground)] hover:text-[var(--vscode-textLink-activeForeground)] flex items-center focus:outline-none'
className={cn(`text-[var(--vscode-textLink-foreground)] hover:text-[var(--vscode-textLink-activeForeground)] flex items-center focus:outline-none ${buttonClass || ""}`)}
disabled={disabled}>
<span>{title}</span>
<ChevronDownIcon className={`-mr-1 ml-1 h-4 w-4`} aria-hidden="true" />

View File

@@ -20,7 +20,8 @@ export const Preview: React.FunctionComponent<IPreviewProps> = ({
const onRefresh = () => {
if (iframeRef.current?.src) {
iframeRef.current.src = iframeRef.current.src;
const url = iframeRef.current.src;
iframeRef.current.src = url;
}
};
@@ -34,10 +35,12 @@ export const Preview: React.FunctionComponent<IPreviewProps> = ({
navUrl = `https://${navUrl}`;
setCrntUrl(navUrl);
}
iframeRef.current!.src = navUrl;
if (iframeRef.current) {
iframeRef.current.src = navUrl;
}
};
const msgListener = (message: MessageEvent<EventData<any>>) => {
const msgListener = (message: MessageEvent<EventData<string>>) => {
if (message.data.command === PreviewCommands.toWebview.updateUrl) {
setCrntUrl(message.data.payload);
}

View File

@@ -5,12 +5,13 @@ import { Startup } from '../Header/Startup';
import { useRecoilValue } from 'recoil';
import { SettingsSelector } from '../../state';
import { SettingsInput } from './SettingsInput';
import { VSCodeButton } from '@vscode/webview-ui-toolkit/react';
import { DOCS_SUBMODULES, FrameworkDetectors, GIT_CONFIG, SETTING_FRAMEWORK_START, SETTING_GIT_COMMIT_MSG, SETTING_GIT_ENABLED, SETTING_PREVIEW_HOST, SETTING_WEBSITE_URL } from '../../../constants';
import { Button as VSCodeButton } from 'vscrui';
import { DOCS_SUBMODULES, FrameworkDetectors, GIT_CONFIG, SETTING_FRAMEWORK_START, SETTING_GIT_COMMIT_MSG, SETTING_GIT_ENABLED, SETTING_PANEL_OPEN_ON_SUPPORTED_FILE, SETTING_PREVIEW_HOST, SETTING_WEBSITE_URL } from '../../../constants';
import { messageHandler } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { SettingsCheckbox } from './SettingsCheckbox';
import { ChevronRightIcon } from '@heroicons/react/24/outline';
import { BooleanOption } from '../Header/BooleanOption';
export interface ICommonSettingsProps { }
@@ -73,6 +74,15 @@ export const CommonSettings: React.FunctionComponent<ICommonSettingsProps> = (pr
<Startup settings={settings} />
</div>
<div className='py-4'>
<h2 className='text-xl mb-2'>{l10n.t(LocalizationKey.settingsOpenPanelForSupportedFiles)}</h2>
<BooleanOption
label={l10n.t(LocalizationKey.settingsOpenPanelForSupportedFilesLabel)}
name={SETTING_PANEL_OPEN_ON_SUPPORTED_FILE}
value={settings?.openPanelForSupportedFiles} />
</div>
<div className='py-4'>
<h2 className='text-xl mb-2'>{l10n.t(LocalizationKey.settingsGit)}</h2>

View File

@@ -4,11 +4,11 @@ import { messageHandler } from '@estruyf/vscode/dist/client';
import { LocalizationKey } from '../../../localization';
import { GeneralCommands, ExtensionState } from '../../../constants';
import { SettingsInput } from './SettingsInput';
import { VSCodeButton } from '@vscode/webview-ui-toolkit/react';
import { Button as VSCodeButton } from 'vscrui';
export interface IIntegrationsViewProps { }
export const IntegrationsView: React.FunctionComponent<IIntegrationsViewProps> = ({ }: React.PropsWithChildren<IIntegrationsViewProps>) => {
export const IntegrationsView: React.FunctionComponent<IIntegrationsViewProps> = () => {
const [deeplApiKey, setDeeplApiKey] = React.useState<string>('');
const [azureApiKey, setAzureApiKey] = React.useState<string>('');
const [azureRegion, setAzureRegion] = React.useState<string>('');

View File

@@ -1,5 +1,5 @@
import { VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
import * as React from 'react';
import { Checkbox as VSCodeCheckbox } from 'vscrui';
export interface ISettingsCheckboxProps {
label: string;
@@ -27,7 +27,7 @@ export const SettingsCheckbox: React.FunctionComponent<ISettingsCheckboxProps> =
return (
<VSCodeCheckbox
onChange={(e: React.ChangeEvent<HTMLInputElement>) => updateValue(e.target.checked)}
onChange={updateValue}
checked={isEnabled}>
{label}
</VSCodeCheckbox>

View File

@@ -1,5 +1,5 @@
import { VSCodeTextField } from '@vscode/webview-ui-toolkit/react';
import * as React from 'react';
import { TextField as VSCodeTextField } from 'vscrui';
export interface ISettingsInputProps {
label: string;
@@ -21,13 +21,10 @@ export const SettingsInput: React.FunctionComponent<ISettingsInputProps> = ({
return (
<VSCodeTextField
className='w-full p-0 m-0 bg-inherit border-0 focus:border-0 outline-none focus:outline-none shadow-none'
style={{
boxShadow: 'none'
}}
className='w-full p-0 m-0 bg-inherit'
value={value || fallback || ""}
placeholder={placeholder}
onInput={(e: React.ChangeEvent<HTMLInputElement>) => onChange(name, e.target.value)}>
onChange={(value: string) => onChange(name, value)}>
{label}
</VSCodeTextField>
);

View File

@@ -8,14 +8,14 @@ import { AstroContentTypes } from '../Configuration/Astro/AstroContentTypes';
import { ContentFolders } from '../Configuration/Common/ContentFolders';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { COMMAND_NAME, TelemetryEvent } from '../../../constants';
import { COMMAND_NAME } from '../../../constants';
import { ArrowPathIcon } from '@heroicons/react/24/outline';
import { VSCodePanelTab, VSCodePanelView, VSCodePanels } from '@vscode/webview-ui-toolkit/react';
import { CommonSettings } from './CommonSettings';
import { IntegrationsView } from './IntegrationsView';
import { useEffect } from 'react';
import { Messenger } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { ITab, IView, Panels as VSCodePanels } from 'vscrui';
export interface ISettingsViewProps { }
@@ -23,12 +23,76 @@ export const SettingsView: React.FunctionComponent<ISettingsViewProps> = (_: Rea
const [loading, setLoading] = React.useState<boolean>(false);
const settings = useRecoilValue(SettingsSelector);
const tabs: ITab[] = React.useMemo(() => {
const temp = [
{ id: "view-1", label: l10n.t(LocalizationKey.settingsViewCommon) },
{ id: "view-2", label: l10n.t(LocalizationKey.settingsViewContentFolders) }
];
if (settings?.crntFramework === 'astro') {
temp.push({ id: "view-3", label: l10n.t(LocalizationKey.settingsViewAstro) });
}
return [
...temp,
{ id: "view-4", label: l10n.t(LocalizationKey.settingsViewIntegration) }
];
}, [settings]);
const views: IView[] = React.useMemo(() => {
if (!settings) {
return [];
}
const temp = [
{
id: "view-1",
content: <CommonSettings />
},
{
id: "view-2",
content: (
<div className='py-4'>
<h2 className='text-xl mb-2'>{l10n.t(LocalizationKey.settingsContentFolders)}</h2>
<ContentFolders
settings={settings}
triggerLoading={(isLoading) => setLoading(isLoading)} />
</div>
)
}
];
if (settings?.crntFramework === 'astro') {
temp.push({
id: "view-3",
content: (
<div className='py-4'>
<h2 className='text-xl mb-2'>{l10n.t(LocalizationKey.settingsContentTypes)}</h2>
<AstroContentTypes
settings={settings}
triggerLoading={(isLoading) => setLoading(isLoading)}
setStatus={_ => null} />
</div>
)
});
}
temp.push({
id: "view-4",
content: (
<IntegrationsView />
)
});
return [
...temp
];
}, [settings]);
useEffect(() => {
Messenger.send(DashboardMessage.setTitle, l10n.t(LocalizationKey.commonSettings));
Messenger.send(DashboardMessage.sendTelemetry, {
event: TelemetryEvent.webviewSettings
});
}, []);
return (
@@ -56,51 +120,11 @@ export const SettingsView: React.FunctionComponent<ISettingsViewProps> = (_: Rea
</a>
</div>
<VSCodePanels className={`mt-4`}>
<VSCodePanelTab id="view-1">{l10n.t(LocalizationKey.settingsViewCommon)}</VSCodePanelTab>
<VSCodePanelTab id="view-2">{l10n.t(LocalizationKey.settingsViewContentFolders)}</VSCodePanelTab>
{
settings?.crntFramework === 'astro' && (
<VSCodePanelTab id="view-3">{l10n.t(LocalizationKey.settingsViewAstro)}</VSCodePanelTab>
)
}
<VSCodePanelTab id="view-4">{l10n.t(LocalizationKey.settingsViewIntegration)}</VSCodePanelTab>
<VSCodePanelView id="view-1">
<CommonSettings />
</VSCodePanelView>
<VSCodePanelView id="view-2">
<div className='py-4'>
<h2 className='text-xl mb-2'>{l10n.t(LocalizationKey.settingsContentFolders)}</h2>
<ContentFolders
settings={settings}
triggerLoading={(isLoading) => setLoading(isLoading)} />
</div>
</VSCodePanelView>
{
settings?.crntFramework === 'astro' && (
<VSCodePanelView id="view-3">
<div className='py-4'>
<h2 className='text-xl mb-2'>{l10n.t(LocalizationKey.settingsContentTypes)}</h2>
<AstroContentTypes
settings={settings}
triggerLoading={(isLoading) => setLoading(isLoading)}
setStatus={_ => null} />
</div>
</VSCodePanelView>
)
}
<VSCodePanelView id="view-4">
<IntegrationsView />
</VSCodePanelView>
</VSCodePanels>
<VSCodePanels
className={`mt-4`}
tabs={tabs}
views={views}
/>
</div>
)
}

View File

@@ -19,6 +19,7 @@ import { LocalizationKey } from '../../../localization';
import { FooterActions } from './FooterActions';
import { ItemMenu } from './ItemMenu';
import { SlideOver } from '../Modals/SlideOver';
import { DEFAULT_DASHBOARD_FEATURE_FLAGS } from '../../../constants/DefaultFeatureFlags';
export interface IItemProps {
snippetKey: string;
@@ -74,7 +75,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({
return;
}
let snippets: Snippets = Object.assign({}, settings?.snippets || {});
const snippets: Snippets = Object.assign({}, settings?.snippets || {});
const snippetLines = snippetOriginalBody.split('\n');
const crntSnippet = Object.assign({}, snippets[snippetKey]);
@@ -163,7 +164,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({
</h2>
<FeatureFlag
features={mode?.features || []}
features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS}
flag={FEATURE_FLAG.dashboard.snippets.manage}
alternative={
<ItemMenu
@@ -182,7 +183,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({
<div className='inline-block mr-1 mt-1 text-xs text-[var(--vscode-button-secondaryForeground)] bg-[var(--vscode-button-secondaryBackground)] border border-[var(--frontmatter-border)] rounded px-1 py-0.5'>
{
snippet.isMediaSnippet ? l10n.t(LocalizationKey.dashboardSnippetsViewItemTypeContent) : l10n.t(LocalizationKey.dashboardSnippetsViewItemTypeMedia)
snippet.isMediaSnippet ? l10n.t(LocalizationKey.dashboardSnippetsViewItemTypeMedia) : l10n.t(LocalizationKey.dashboardSnippetsViewItemTypeContent)
}
</div>
@@ -190,7 +191,7 @@ export const Item: React.FunctionComponent<IItemProps> = ({
</div>
<FeatureFlag
features={mode?.features || []}
features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS}
flag={FEATURE_FLAG.dashboard.snippets.manage}
alternative={
<FooterActions

View File

@@ -79,11 +79,11 @@ const SnippetForm: React.ForwardRefRenderFunction<SnippetFormHandle, ISnippetFor
);
const snippetBody = useMemo(() => {
let body = typeof snippet.body === 'string' ? snippet.body : snippet.body.join(`\n`);
const body = typeof snippet.body === 'string' ? snippet.body : snippet.body.join(`\n`);
const obj: any = {};
const obj: { [key: string]: string } = {};
for (const field of fields) {
obj[field.name] = field.value;
obj[field.name] = field.value as string;
}
return SnippetParser.render(body, obj, snippet.openingTags, snippet.closingTags);

View File

@@ -31,7 +31,7 @@ export const SnippetInputField: React.FunctionComponent<ISnippetInputFieldProps>
<div className="relative">
<select
name={field.name}
value={field.value || ''}
value={field.value as string || ''}
className={`block w-full sm:text-sm pr-2 appearance-none disabled:opacity-50 rounded bg-[var(--vscode-input-background)] text-[var(--vscode-input-foreground)] placeholder-[var(--vscode-input-placeholderForeground)] border-[var(--frontmatter-border)] focus:border-[var(--vscode-focusBorder)] focus:outline-0`}
style={{
boxShadow: "none"
@@ -69,7 +69,7 @@ export const SnippetInputField: React.FunctionComponent<ISnippetInputFieldProps>
return (
<TextField
name={field.name}
value={field.value || ''}
value={field.value as string || ''}
description={field.description}
onChange={(e) => onValueChange(field, e)}
rows={4}
@@ -81,7 +81,7 @@ export const SnippetInputField: React.FunctionComponent<ISnippetInputFieldProps>
return (
<TextField
name={field.name}
value={field.value || ''}
value={field.value as string || ''}
description={field.description}
onChange={(e) => onValueChange(field, e)}
/>

View File

@@ -5,7 +5,6 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { FeatureFlag } from '../../../components/features/FeatureFlag';
import { FEATURE_FLAG, GeneralCommands, WEBSITE_LINKS } from '../../../constants';
import { TelemetryEvent } from '../../../constants/TelemetryEvent';
import { SnippetParser } from '../../../helpers/SnippetParser';
import { DashboardMessage } from '../../DashboardMessage';
import { ModeAtom, SettingsSelector, ViewDataSelector } from '../../state';
@@ -18,6 +17,7 @@ import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { List } from '../Media/List';
import { SlideOver } from '../Modals/SlideOver';
import { DEFAULT_DASHBOARD_FEATURE_FLAGS } from '../../../constants/DefaultFeatureFlags';
export interface ISnippetsProps { }
@@ -83,10 +83,6 @@ export const Snippets: React.FunctionComponent<ISnippetsProps> = (
useEffect(() => {
Messenger.send(DashboardMessage.setTitle, l10n.t(LocalizationKey.dashboardHeaderTabsSnippets));
Messenger.send(DashboardMessage.sendTelemetry, {
event: TelemetryEvent.webviewSnippetsView
});
Messenger.send(GeneralCommands.toVSCode.logging.info, {
message: `Snippets view loaded`,
location: 'DASHBOARD'
@@ -96,7 +92,9 @@ export const Snippets: React.FunctionComponent<ISnippetsProps> = (
return (
<PageLayout
header={
<FeatureFlag features={mode?.features || []} flag={FEATURE_FLAG.dashboard.snippets.manage}>
<FeatureFlag
features={mode?.features || DEFAULT_DASHBOARD_FEATURE_FLAGS}
flag={FEATURE_FLAG.dashboard.snippets.manage}>
<div
className={`py-3 px-4 flex items-center justify-between border-b border-[var(--frontmatter-border)]`}
aria-label={l10n.t(LocalizationKey.dashboardSnippetsViewSnippetsAriaLabel)}

View File

@@ -17,7 +17,7 @@ import { TemplateItem } from './TemplateItem';
import { Spinner } from '../Common/Spinner';
import { AstroContentTypes } from '../Configuration/Astro/AstroContentTypes';
import { ContentFolders } from '../Configuration/Common/ContentFolders';
import { VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
import { Checkbox as VSCodeCheckbox } from 'vscrui';
import { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuSeparator } from '../../../components/shadcn/Dropdown';
export interface IStepsToGetStartedProps {
@@ -239,7 +239,7 @@ export const StepsToGetStarted: React.FunctionComponent<IStepsToGetStartedProps>
description: (
<div className='mt-1'>
<VSCodeCheckbox
onChange={(e: React.ChangeEvent<HTMLInputElement>) => updateSetting(SETTING_GIT_ENABLED, e.target.checked)}
onChange={(value) => updateSetting(SETTING_GIT_ENABLED, value)}
checked={isGitEnabled}>
{l10n.t(LocalizationKey.dashboardStepsStepsToGetStartedGitDescription)}
</VSCodeCheckbox>

View File

@@ -41,7 +41,7 @@ export const TaxonomyLookup: React.FunctionComponent<ITaxonomyLookupProps> = ({
return false;
}
let fieldName = getTaxonomyField(taxonomy, contentType);
const fieldName = getTaxonomyField(taxonomy, contentType);
return fieldName && page[fieldName] ? page[fieldName].includes(value) : false;
}).length;

View File

@@ -80,7 +80,7 @@ export const TaxonomyManager: React.FunctionComponent<ITaxonomyManagerProps> = (
}, [data, taxonomy, debounceFilterValue]);
const unmappedItems = useMemo(() => {
let unmapped: string[] = [];
const unmapped: string[] = [];
if (!pages || !settings?.contentTypes || !taxonomy) {
return unmapped;
@@ -100,7 +100,7 @@ export const TaxonomyManager: React.FunctionComponent<ITaxonomyManagerProps> = (
return false;
}
let fieldName = getTaxonomyField(taxonomy, contentType);
const fieldName = getTaxonomyField(taxonomy, contentType);
if (fieldName && page[fieldName]) {
values = page[fieldName];

View File

@@ -5,18 +5,18 @@ import { SettingsSelector } from '../../state';
import { getTaxonomyField } from '../../../helpers/getTaxonomyField';
import { Sorting } from '../../../helpers/Sorting';
import { ArrowLeftIcon, EyeIcon } from '@heroicons/react/24/outline';
import { Button } from '../Common/Button';
import { VSCodeCheckbox } from '@vscode/webview-ui-toolkit/react';
import { Button } from 'vscrui';
import { FilterInput } from './FilterInput';
import { useDebounce } from '../../../hooks/useDebounce';
import * as l10n from '@vscode/l10n';
import { LocalizationKey } from '../../../localization';
import { sortPages } from '../../../utils/sortPages';
import { Messenger, messageHandler } from '@estruyf/vscode/dist/client';
import { messageHandler } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { ExtensionState } from '../../../constants';
import { LinkButton } from '../Common/LinkButton';
import { openFile } from '../../utils';
import { Checkbox as VSCodeCheckbox } from 'vscrui';
export interface ITaxonomyTaggingProps {
taxonomy: string | null;
@@ -70,7 +70,7 @@ export const TaxonomyTagging: React.FunctionComponent<ITaxonomyTaggingProps> = (
continue;
}
let fieldName = getTaxonomyField(taxonomy, contentType);
const fieldName = getTaxonomyField(taxonomy, contentType);
if (fieldName && (!page[fieldName] || page[fieldName].indexOf(value) === -1)) {
untagged.push(page);
@@ -78,7 +78,7 @@ export const TaxonomyTagging: React.FunctionComponent<ITaxonomyTaggingProps> = (
}
}
untagged = untagged.sort(Sorting.number('fmPublished')).reverse();
untagged = untagged.sort(Sorting.numerically('fmPublished')).reverse();
if (debounceFilterValue) {
return untagged.filter((p) => p.title.toLowerCase().includes(debounceFilterValue.toLowerCase()));
@@ -122,8 +122,12 @@ export const TaxonomyTagging: React.FunctionComponent<ITaxonomyTaggingProps> = (
}, [pageMappings, untaggedPages]);
const checkIfChecked = React.useCallback((page: Page) => {
return (!untaggedPages.find((p: Page) => p.fmFilePath === page.fmFilePath) && !pageMappings.untagged.find((p: Page) => p.fmFilePath === page.fmFilePath)) || pageMappings.tagged.find((p: Page) => p.fmFilePath === page.fmFilePath);
}, [untaggedPages, pageMappings.tagged]);
const isUntagged = untaggedPages.some((p) => p.fmFilePath === page.fmFilePath);
const isTagged = pageMappings.tagged.some((p) => p.fmFilePath === page.fmFilePath);
const isInUntagged = pageMappings.untagged.some((p) => p.fmFilePath === page.fmFilePath);
return (!isUntagged && !isInUntagged) || isTagged;
}, [untaggedPages, pageMappings.tagged, pageMappings.untagged]);
const onFileView = (filePath: string) => {
openFile(filePath);
@@ -193,7 +197,7 @@ export const TaxonomyTagging: React.FunctionComponent<ITaxonomyTaggingProps> = (
<td className={`pl-6 py-2 w-[25px]`}>
<VSCodeCheckbox
title={l10n.t(LocalizationKey.dashboardTaxonomyViewTaxonomyTaggingCheckbox, value)}
onClick={() => onCheckboxClick(page)}
onChange={() => onCheckboxClick(page)}
checked={checkIfChecked(page)}>
<span className='sr-only'>
{l10n.t(LocalizationKey.dashboardTaxonomyViewTaxonomyTaggingCheckbox, value)}
@@ -225,8 +229,8 @@ export const TaxonomyTagging: React.FunctionComponent<ITaxonomyTaggingProps> = (
</div>
<div className='flex justify-end space-x-2'>
<Button onClick={onDismiss} secondary>{l10n.t(LocalizationKey.commonCancel)}</Button>
<Button onClick={() => onContentMapping(value, pageMappings)}>{l10n.t(LocalizationKey.commonApply)}</Button>
<Button className='!py-2' onClick={onDismiss} appearance='secondary'>{l10n.t(LocalizationKey.commonCancel)}</Button>
<Button className='!py-2' onClick={() => onContentMapping(value, pageMappings)}>{l10n.t(LocalizationKey.commonApply)}</Button>
</div>
</div>
);

View File

@@ -3,7 +3,7 @@ import { ChevronRightIcon, ArrowDownTrayIcon } from '@heroicons/react/24/outline
import * as React from 'react';
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { GeneralCommands, TelemetryEvent } from '../../../constants';
import { GeneralCommands } from '../../../constants';
import { TaxonomyData } from '../../../models';
import { DashboardMessage } from '../../DashboardMessage';
import { Page, PageMappings } from '../../models';
@@ -55,10 +55,6 @@ export const TaxonomyView: React.FunctionComponent<ITaxonomyViewProps> = ({
useEffect(() => {
Messenger.send(DashboardMessage.setTitle, l10n.t(LocalizationKey.dashboardHeaderTabsTaxonomies));
Messenger.send(DashboardMessage.sendTelemetry, {
event: TelemetryEvent.webviewTaxonomyDashboard
});
Messenger.send(GeneralCommands.toVSCode.logging.info, {
message: 'Taxonomy view loaded',
location: 'DASHBOARD'

View File

@@ -5,7 +5,6 @@ import { LocalizationKey } from '../../../localization';
import { useEffect } from 'react';
import { Messenger } from '@estruyf/vscode/dist/client';
import { DashboardMessage } from '../../DashboardMessage';
import { TelemetryEvent } from '../../../constants';
export interface IUnknownViewProps { }
@@ -14,10 +13,6 @@ export const UnknownView: React.FunctionComponent<IUnknownViewProps> = (
) => {
useEffect(() => {
Messenger.send(DashboardMessage.setTitle, "Unknown View");
Messenger.send(DashboardMessage.sendTelemetry, {
event: TelemetryEvent.webviewUnknown
});
}, []);
return (

View File

@@ -1,6 +1,6 @@
import { BookOpenIcon, HeartIcon, StarIcon } from '@heroicons/react/24/outline';
import * as React from 'react';
import { DOCUMENTATION_LINK, GITHUB_LINK, GeneralCommands, REVIEW_LINK, SPONSOR_LINK, TelemetryEvent } from '../../../constants';
import { DOCUMENTATION_LINK, GITHUB_LINK, GeneralCommands, REVIEW_LINK, SPONSOR_LINK } from '../../../constants';
import { Messenger } from '@estruyf/vscode/dist/client';
import { FrontMatterIcon } from '../../../panelWebView/components/Icons/FrontMatterIcon';
import { GitHubIcon } from '../../../panelWebView/components/Icons/GitHubIcon';
@@ -25,9 +25,6 @@ export const WelcomeScreen: React.FunctionComponent<IWelcomeScreenProps> = ({
React.useEffect(() => {
setView(NavigationType.Welcome);
Messenger.send(DashboardMessage.sendTelemetry, {
event: TelemetryEvent.webviewWelcomeScreen
});
Messenger.send(GeneralCommands.toVSCode.logging.info, {
message: 'Welcome screen loaded',

Some files were not shown because too many files have changed in this diff Show More