added page export and import
This commit is contained in:
parent
f459dd8812
commit
93ab5fbea2
|
@ -24,10 +24,10 @@
|
||||||
window.Prism = window.Prism || {};
|
window.Prism = window.Prism || {};
|
||||||
window.Prism.manual = true;
|
window.Prism.manual = true;
|
||||||
</script>
|
</script>
|
||||||
<script src="./libs/diff/diff.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<script type="module" src="./src/main.js"></script>
|
<script type="module" src="./src/main.js"></script>
|
||||||
|
<script src="./libs/diff/diff.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@codemirror/autocomplete": "^6.0.0",
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
"@codemirror/commands": "^6.0.0",
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
"@codemirror/lang-javascript": "^6.0.2",
|
||||||
|
"@codemirror/lang-json": "^6.0.0",
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
"@codemirror/legacy-modes": "^6.0.0",
|
"@codemirror/legacy-modes": "^6.0.0",
|
||||||
"@codemirror/search": "^6.0.0",
|
"@codemirror/search": "^6.0.0",
|
||||||
|
@ -17,7 +19,7 @@
|
||||||
"chart.js": "^3.7.1",
|
"chart.js": "^3.7.1",
|
||||||
"chartjs-adapter-luxon": "^1.1.0",
|
"chartjs-adapter-luxon": "^1.1.0",
|
||||||
"luxon": "^2.3.2",
|
"luxon": "^2.3.2",
|
||||||
"pocketbase": "^0.3.0",
|
"pocketbase": "../../js-sdk",
|
||||||
"prismjs": "^1.28.0",
|
"prismjs": "^1.28.0",
|
||||||
"sass": "^1.45.0",
|
"sass": "^1.45.0",
|
||||||
"svelte": "^3.44.0",
|
"svelte": "^3.44.0",
|
||||||
|
@ -26,6 +28,34 @@
|
||||||
"vite": "^3.0.0"
|
"vite": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"../../js-sdk": {
|
||||||
|
"name": "pocketbase",
|
||||||
|
"version": "0.3.0",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"devDependencies": {
|
||||||
|
"@rollup/plugin-commonjs": "^21.0.0",
|
||||||
|
"@rollup/plugin-json": "^4.1.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||||
|
"@types/chai": "^4.2.19",
|
||||||
|
"@types/chai-as-promised": "^7.1.4",
|
||||||
|
"@types/glob": "^7.1.3",
|
||||||
|
"@types/mocha": "^8.2.2",
|
||||||
|
"@types/sinon": "^10.0.11",
|
||||||
|
"chai": "^4.3.4",
|
||||||
|
"chai-as-promised": "^7.1.1",
|
||||||
|
"glob": "^7.1.7",
|
||||||
|
"mocha": "^9.0.1",
|
||||||
|
"node-fetch": "^3.2.8",
|
||||||
|
"rollup": "^2.63.0",
|
||||||
|
"rollup-plugin-terser": "^7.0.0",
|
||||||
|
"rollup-plugin-ts": "^2.0.0",
|
||||||
|
"ts-node": "^10.0.0",
|
||||||
|
"tsconfig-paths": "^3.9.0",
|
||||||
|
"tslib": "^2.3.0",
|
||||||
|
"typescript": "4.6.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@codemirror/autocomplete": {
|
"node_modules/@codemirror/autocomplete": {
|
||||||
"version": "6.1.0",
|
"version": "6.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.1.0.tgz",
|
||||||
|
@ -56,6 +86,31 @@
|
||||||
"@lezer/common": "^1.0.0"
|
"@lezer/common": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@codemirror/lang-javascript": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-BZRJ9u/zl16hLkSpDAWm73mrfIR7HJrr0lvnhoSOCQVea5BglguWI/slxexhvUb0CB5cXgKWuo2bM+N9EhIaZw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/lint": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"@lezer/common": "^1.0.0",
|
||||||
|
"@lezer/javascript": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@codemirror/lang-json": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-DvTcYTKLmg2viADXlTdufrT334M9jowe1qO02W28nvm+nejcvhM5vot5mE8/kPrxYw/HJHhwu1z2PyBpnMLCNQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@lezer/json": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@codemirror/language": {
|
"node_modules/@codemirror/language": {
|
||||||
"version": "6.2.1",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
|
||||||
|
@ -79,6 +134,17 @@
|
||||||
"@codemirror/language": "^6.0.0"
|
"@codemirror/language": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@codemirror/lint": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-nUUXcJW1Xp54kNs+a1ToPLK8MadO0rMTnJB8Zk4Z8gBdrN0kqV7uvUraU/T2yqg+grDNR38Vmy/MrhQN/RgwiA==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"crelt": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@codemirror/search": {
|
"node_modules/@codemirror/search": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.1.tgz",
|
||||||
|
@ -138,6 +204,26 @@
|
||||||
"@lezer/common": "^1.0.0"
|
"@lezer/common": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@lezer/javascript": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-IjOVeIRhM8IuafWNnk+UzRz7p4/JSOKBNINLYLsdSGuJS9Ju7vFdc82AlTt0jgtV5D8eBZf4g0vK4d3ttBNz7A==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@lezer/highlight": "^1.0.0",
|
||||||
|
"@lezer/lr": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lezer/json": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-zbAuUY09RBzCoCA3lJ1+ypKw5WSNvLqGMtasdW6HvVOqZoCpPr8eWrsGnOVWGKGn8Rh21FnrKRVlJXrGAVUqRw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@lezer/highlight": "^1.0.0",
|
||||||
|
"@lezer/lr": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@lezer/lr": {
|
"node_modules/@lezer/lr": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.1.tgz",
|
||||||
|
@ -862,10 +948,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/pocketbase": {
|
"node_modules/pocketbase": {
|
||||||
"version": "0.3.0",
|
"resolved": "../../js-sdk",
|
||||||
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.3.0.tgz",
|
"link": true
|
||||||
"integrity": "sha512-8D1X23zF0Qroq0uecKCBFs3yuD5MsYvGU0S+e/adIz7xH1N0CJiyhRZzPNbTKM9CcLPA8INFc/ct1YXxcO+jfQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"node_modules/postcss": {
|
"node_modules/postcss": {
|
||||||
"version": "8.4.14",
|
"version": "8.4.14",
|
||||||
|
@ -1133,6 +1217,31 @@
|
||||||
"@lezer/common": "^1.0.0"
|
"@lezer/common": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@codemirror/lang-javascript": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-BZRJ9u/zl16hLkSpDAWm73mrfIR7HJrr0lvnhoSOCQVea5BglguWI/slxexhvUb0CB5cXgKWuo2bM+N9EhIaZw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@codemirror/lint": "^6.0.0",
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"@lezer/common": "^1.0.0",
|
||||||
|
"@lezer/javascript": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@codemirror/lang-json": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-DvTcYTKLmg2viADXlTdufrT334M9jowe1qO02W28nvm+nejcvhM5vot5mE8/kPrxYw/HJHhwu1z2PyBpnMLCNQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@codemirror/language": "^6.0.0",
|
||||||
|
"@lezer/json": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@codemirror/language": {
|
"@codemirror/language": {
|
||||||
"version": "6.2.1",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.2.1.tgz",
|
||||||
|
@ -1156,6 +1265,17 @@
|
||||||
"@codemirror/language": "^6.0.0"
|
"@codemirror/language": "^6.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@codemirror/lint": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-nUUXcJW1Xp54kNs+a1ToPLK8MadO0rMTnJB8Zk4Z8gBdrN0kqV7uvUraU/T2yqg+grDNR38Vmy/MrhQN/RgwiA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@codemirror/state": "^6.0.0",
|
||||||
|
"@codemirror/view": "^6.0.0",
|
||||||
|
"crelt": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@codemirror/search": {
|
"@codemirror/search": {
|
||||||
"version": "6.0.1",
|
"version": "6.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.0.1.tgz",
|
||||||
|
@ -1206,6 +1326,26 @@
|
||||||
"@lezer/common": "^1.0.0"
|
"@lezer/common": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@lezer/javascript": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-IjOVeIRhM8IuafWNnk+UzRz7p4/JSOKBNINLYLsdSGuJS9Ju7vFdc82AlTt0jgtV5D8eBZf4g0vK4d3ttBNz7A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@lezer/highlight": "^1.0.0",
|
||||||
|
"@lezer/lr": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@lezer/json": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-zbAuUY09RBzCoCA3lJ1+ypKw5WSNvLqGMtasdW6HvVOqZoCpPr8eWrsGnOVWGKGn8Rh21FnrKRVlJXrGAVUqRw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@lezer/highlight": "^1.0.0",
|
||||||
|
"@lezer/lr": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@lezer/lr": {
|
"@lezer/lr": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.1.tgz",
|
||||||
|
@ -1638,10 +1778,29 @@
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"pocketbase": {
|
"pocketbase": {
|
||||||
"version": "0.3.0",
|
"version": "file:../../js-sdk",
|
||||||
"resolved": "https://registry.npmjs.org/pocketbase/-/pocketbase-0.3.0.tgz",
|
"requires": {
|
||||||
"integrity": "sha512-8D1X23zF0Qroq0uecKCBFs3yuD5MsYvGU0S+e/adIz7xH1N0CJiyhRZzPNbTKM9CcLPA8INFc/ct1YXxcO+jfQ==",
|
"@rollup/plugin-commonjs": "^21.0.0",
|
||||||
"dev": true
|
"@rollup/plugin-json": "^4.1.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^13.0.0",
|
||||||
|
"@types/chai": "^4.2.19",
|
||||||
|
"@types/chai-as-promised": "^7.1.4",
|
||||||
|
"@types/glob": "^7.1.3",
|
||||||
|
"@types/mocha": "^8.2.2",
|
||||||
|
"@types/sinon": "^10.0.11",
|
||||||
|
"chai": "^4.3.4",
|
||||||
|
"chai-as-promised": "^7.1.1",
|
||||||
|
"glob": "^7.1.7",
|
||||||
|
"mocha": "^9.0.1",
|
||||||
|
"node-fetch": "^3.2.8",
|
||||||
|
"rollup": "^2.63.0",
|
||||||
|
"rollup-plugin-terser": "^7.0.0",
|
||||||
|
"rollup-plugin-ts": "^2.0.0",
|
||||||
|
"ts-node": "^10.0.0",
|
||||||
|
"tsconfig-paths": "^3.9.0",
|
||||||
|
"tslib": "^2.3.0",
|
||||||
|
"typescript": "4.6.4"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"postcss": {
|
"postcss": {
|
||||||
"version": "8.4.14",
|
"version": "8.4.14",
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@codemirror/autocomplete": "^6.0.0",
|
"@codemirror/autocomplete": "^6.0.0",
|
||||||
"@codemirror/commands": "^6.0.0",
|
"@codemirror/commands": "^6.0.0",
|
||||||
|
"@codemirror/lang-javascript": "^6.0.2",
|
||||||
"@codemirror/language": "^6.0.0",
|
"@codemirror/language": "^6.0.0",
|
||||||
"@codemirror/legacy-modes": "^6.0.0",
|
"@codemirror/legacy-modes": "^6.0.0",
|
||||||
"@codemirror/search": "^6.0.0",
|
"@codemirror/search": "^6.0.0",
|
||||||
|
@ -23,7 +24,7 @@
|
||||||
"chart.js": "^3.7.1",
|
"chart.js": "^3.7.1",
|
||||||
"chartjs-adapter-luxon": "^1.1.0",
|
"chartjs-adapter-luxon": "^1.1.0",
|
||||||
"luxon": "^2.3.2",
|
"luxon": "^2.3.2",
|
||||||
"pocketbase": "^0.3.0",
|
"pocketbase": "../../js-sdk",
|
||||||
"prismjs": "^1.28.0",
|
"prismjs": "^1.28.0",
|
||||||
"sass": "^1.45.0",
|
"sass": "^1.45.0",
|
||||||
"svelte": "^3.44.0",
|
"svelte": "^3.44.0",
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// https://github.com/google/diff-match-patch
|
// https://github.com/google/diff-match-patch
|
||||||
|
// https://github.com/google/diff-match-patch/blob/master/LICENSE
|
||||||
var diff_match_patch=function(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32},DIFF_DELETE=-1,DIFF_INSERT=1,DIFF_EQUAL=0;diff_match_patch.Diff=function(a,b){this[0]=a;this[1]=b};diff_match_patch.Diff.prototype.length=2;diff_match_patch.Diff.prototype.toString=function(){return this[0]+","+this[1]};
|
var diff_match_patch=function(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32},DIFF_DELETE=-1,DIFF_INSERT=1,DIFF_EQUAL=0;diff_match_patch.Diff=function(a,b){this[0]=a;this[1]=b};diff_match_patch.Diff.prototype.length=2;diff_match_patch.Diff.prototype.toString=function(){return this[0]+","+this[1]};
|
||||||
diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[new diff_match_patch.Diff(DIFF_EQUAL,a)]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);f=this.diff_commonSuffix(a,b);var g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,
|
diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[new diff_match_patch.Diff(DIFF_EQUAL,a)]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);f=this.diff_commonSuffix(a,b);var g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,
|
||||||
b.length-f);a=this.diff_compute_(a,b,e,d);c&&a.unshift(new diff_match_patch.Diff(DIFF_EQUAL,c));g&&a.push(new diff_match_patch.Diff(DIFF_EQUAL,g));this.diff_cleanupMerge(a);return a};
|
b.length-f);a=this.diff_compute_(a,b,e,d);c&&a.unshift(new diff_match_patch.Diff(DIFF_EQUAL,c));g&&a.push(new diff_match_patch.Diff(DIFF_EQUAL,g));this.diff_cleanupMerge(a);return a};
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
<script>
|
||||||
|
import { onMount, createEventDispatcher } from "svelte";
|
||||||
|
// code mirror imports
|
||||||
|
// ---
|
||||||
|
import {
|
||||||
|
keymap,
|
||||||
|
highlightSpecialChars,
|
||||||
|
drawSelection,
|
||||||
|
dropCursor,
|
||||||
|
rectangularSelection,
|
||||||
|
EditorView,
|
||||||
|
placeholder as placeholderExt,
|
||||||
|
} from "@codemirror/view";
|
||||||
|
import { EditorState, Compartment } from "@codemirror/state";
|
||||||
|
import { defaultHighlightStyle, syntaxHighlighting, bracketMatching } from "@codemirror/language";
|
||||||
|
import { defaultKeymap, history, historyKeymap, indentWithTab } from "@codemirror/commands";
|
||||||
|
import { searchKeymap, highlightSelectionMatches } from "@codemirror/search";
|
||||||
|
import { closeBrackets, closeBracketsKeymap } from "@codemirror/autocomplete";
|
||||||
|
import { javascript } from "@codemirror/lang-javascript";
|
||||||
|
// ---
|
||||||
|
|
||||||
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
|
export let value = "";
|
||||||
|
export let disabled = false;
|
||||||
|
export let placeholder = "";
|
||||||
|
export let singleLine = false;
|
||||||
|
|
||||||
|
let editor;
|
||||||
|
let container;
|
||||||
|
let editableCompartment = new Compartment();
|
||||||
|
let readOnlyCompartment = new Compartment();
|
||||||
|
let placeholderCompartment = new Compartment();
|
||||||
|
|
||||||
|
$: if (editor && typeof disabled !== "undefined") {
|
||||||
|
editor.dispatch({
|
||||||
|
effects: [
|
||||||
|
editableCompartment.reconfigure(EditorView.editable.of(!disabled)),
|
||||||
|
readOnlyCompartment.reconfigure(EditorState.readOnly.of(disabled)),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
triggerNativeChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if (editor && value != editor.state.doc.toString()) {
|
||||||
|
editor.dispatch({
|
||||||
|
changes: {
|
||||||
|
from: 0,
|
||||||
|
to: editor.state.doc.length,
|
||||||
|
insert: value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$: if (editor && typeof placeholder !== "undefined") {
|
||||||
|
editor.dispatch({
|
||||||
|
effects: [placeholderCompartment.reconfigure(placeholderExt(placeholder))],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Focus the editor (if inited).
|
||||||
|
export function focus() {
|
||||||
|
editor?.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Emulate native change event for the editor container element.
|
||||||
|
function triggerNativeChange() {
|
||||||
|
container?.dispatchEvent(
|
||||||
|
new CustomEvent("change", {
|
||||||
|
detail: { value },
|
||||||
|
bubbles: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const submitShortcut = {
|
||||||
|
key: "Enter",
|
||||||
|
run: (_) => {
|
||||||
|
// trigger submit on enter for singleline input
|
||||||
|
if (singleLine) {
|
||||||
|
dispatch("submit", value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
editor = new EditorView({
|
||||||
|
parent: container,
|
||||||
|
state: EditorState.create({
|
||||||
|
doc: value,
|
||||||
|
extensions: [
|
||||||
|
highlightSpecialChars(),
|
||||||
|
history(),
|
||||||
|
drawSelection(),
|
||||||
|
dropCursor(),
|
||||||
|
EditorState.allowMultipleSelections.of(true),
|
||||||
|
syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
|
||||||
|
bracketMatching(),
|
||||||
|
closeBrackets(),
|
||||||
|
rectangularSelection(),
|
||||||
|
highlightSelectionMatches(),
|
||||||
|
keymap.of([
|
||||||
|
submitShortcut,
|
||||||
|
indentWithTab,
|
||||||
|
...closeBracketsKeymap,
|
||||||
|
...defaultKeymap,
|
||||||
|
...searchKeymap,
|
||||||
|
...historyKeymap,
|
||||||
|
]),
|
||||||
|
EditorView.lineWrapping,
|
||||||
|
javascript(),
|
||||||
|
placeholderCompartment.of(placeholderExt(placeholder)),
|
||||||
|
editableCompartment.of(EditorView.editable.of(true)),
|
||||||
|
readOnlyCompartment.of(EditorState.readOnly.of(false)),
|
||||||
|
EditorState.transactionFilter.of((tr) => {
|
||||||
|
return singleLine && tr.newDoc.lines > 1 ? [] : tr;
|
||||||
|
}),
|
||||||
|
EditorView.updateListener.of((v) => {
|
||||||
|
if (!v.docChanged || disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
value = v.state.doc.toString();
|
||||||
|
triggerNativeChange();
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => editor?.destroy();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div bind:this={container} class="code-editor" />
|
|
@ -0,0 +1,96 @@
|
||||||
|
<script>
|
||||||
|
import OverlayPanel from "@/components/base/OverlayPanel.svelte";
|
||||||
|
|
||||||
|
export let title = "Side-by-side diff";
|
||||||
|
export let contentATitle = "Old state";
|
||||||
|
export let contentBTitle = "New state";
|
||||||
|
|
||||||
|
let panel;
|
||||||
|
let contentA = "";
|
||||||
|
let contentB = "";
|
||||||
|
|
||||||
|
export function show(a, b) {
|
||||||
|
contentA = a;
|
||||||
|
contentB = b;
|
||||||
|
|
||||||
|
panel?.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hide() {
|
||||||
|
return panel?.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function diffsToHtml(diffs, ops = [DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL]) {
|
||||||
|
const html = [];
|
||||||
|
const pattern_amp = /&/g;
|
||||||
|
const pattern_lt = /</g;
|
||||||
|
const pattern_gt = />/g;
|
||||||
|
const pattern_para = /\n/g;
|
||||||
|
|
||||||
|
for (let i = 0; i < diffs.length; i++) {
|
||||||
|
const op = diffs[i][0]; // operation (insert, delete, equal)
|
||||||
|
|
||||||
|
if (!ops.includes(op)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = diffs[i][1]
|
||||||
|
.replace(pattern_amp, "&")
|
||||||
|
.replace(pattern_lt, "<")
|
||||||
|
.replace(pattern_gt, ">")
|
||||||
|
.replace(pattern_para, "<br>");
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case DIFF_INSERT:
|
||||||
|
html[i] = '<ins class="block">' + text + "</ins>";
|
||||||
|
break;
|
||||||
|
case DIFF_DELETE:
|
||||||
|
html[i] = '<del class="block">' + text + "</del>";
|
||||||
|
break;
|
||||||
|
case DIFF_EQUAL:
|
||||||
|
html[i] = text;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return html.join("");
|
||||||
|
}
|
||||||
|
|
||||||
|
function diff(ops = [DIFF_INSERT, DIFF_DELETE, DIFF_EQUAL]) {
|
||||||
|
const dmp = new diff_match_patch();
|
||||||
|
const lines = dmp.diff_linesToChars_(contentA, contentB);
|
||||||
|
const diffs = dmp.diff_main(lines.chars1, lines.chars2, false);
|
||||||
|
|
||||||
|
dmp.diff_charsToLines_(diffs, lines.lineArray);
|
||||||
|
|
||||||
|
return diffsToHtml(diffs, ops);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<OverlayPanel bind:this={panel} class="full-width-popup diff-popup" popup on:show on:hide>
|
||||||
|
<svelte:fragment slot="header">
|
||||||
|
<h4 class="center txt-break">{title}</h4>
|
||||||
|
</svelte:fragment>
|
||||||
|
|
||||||
|
<div class="grid m-b-base">
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="section-title">{contentATitle}</div>
|
||||||
|
<code class="code-block">{@html diff([DIFF_DELETE, DIFF_EQUAL])}</code>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<div class="section-title">{contentBTitle}</div>
|
||||||
|
<code class="code-block">{@html diff([DIFF_INSERT, DIFF_EQUAL])}</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<svelte:fragment slot="footer">
|
||||||
|
<button type="button" class="btn btn-secondary" on:click={hide}>Close</button>
|
||||||
|
</svelte:fragment>
|
||||||
|
</OverlayPanel>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
code {
|
||||||
|
color: var(--txtHintColor);
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
const uniqueId = "export_" + CommonHelper.randomString(5);
|
const uniqueId = "export_" + CommonHelper.randomString(5);
|
||||||
|
|
||||||
|
let previewContainer;
|
||||||
let collections = [];
|
let collections = [];
|
||||||
let isLoadingCollections = false;
|
let isLoadingCollections = false;
|
||||||
|
|
||||||
|
@ -68,7 +69,22 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="export-preview">
|
<div
|
||||||
|
tabindex="0"
|
||||||
|
bind:this={previewContainer}
|
||||||
|
class="export-preview"
|
||||||
|
on:keydown={(e) => {
|
||||||
|
// select all
|
||||||
|
if (e.ctrlKey && e.code === "KeyA") {
|
||||||
|
e.preventDefault();
|
||||||
|
const selection = window.getSelection();
|
||||||
|
const range = document.createRange();
|
||||||
|
range.selectNodeContents(previewContainer);
|
||||||
|
selection.removeAllRanges();
|
||||||
|
selection.addRange(range);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
class="btn btn-sm btn-secondary fade copy-schema"
|
class="btn btn-sm btn-secondary fade copy-schema"
|
||||||
|
|
|
@ -1,23 +1,24 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { tick } from "svelte";
|
||||||
import ApiClient from "@/utils/ApiClient";
|
import ApiClient from "@/utils/ApiClient";
|
||||||
import CommonHelper from "@/utils/CommonHelper";
|
import CommonHelper from "@/utils/CommonHelper";
|
||||||
import { pageTitle } from "@/stores/app";
|
import { pageTitle } from "@/stores/app";
|
||||||
import { addInfoToast, addErrorToast } from "@/stores/toasts";
|
import { addInfoToast, addErrorToast } from "@/stores/toasts";
|
||||||
import Field from "@/components/base/Field.svelte";
|
import Field from "@/components/base/Field.svelte";
|
||||||
import CodeBlock from "@/components/base/CodeBlock.svelte";
|
import DiffPopup from "@/components/base/DiffPopup.svelte";
|
||||||
import SettingsSidebar from "@/components/settings/SettingsSidebar.svelte";
|
import SettingsSidebar from "@/components/settings/SettingsSidebar.svelte";
|
||||||
|
|
||||||
$pageTitle = "Import collections";
|
$pageTitle = "Import collections";
|
||||||
|
|
||||||
let uniquePageId = "import_" + CommonHelper.randomString(5);
|
|
||||||
|
|
||||||
let fileInput;
|
let fileInput;
|
||||||
|
let diffPopup;
|
||||||
|
|
||||||
let schema = "";
|
let schema = "";
|
||||||
let isImporting = false;
|
let isImporting = false;
|
||||||
let isLoadingFile = false;
|
let isLoadingFile = false;
|
||||||
let newCollections = [];
|
let newCollections = [];
|
||||||
let oldCollections = [];
|
let oldCollections = [];
|
||||||
|
let collectionsToModify = [];
|
||||||
let isLoadingOldCollections = false;
|
let isLoadingOldCollections = false;
|
||||||
|
|
||||||
$: if (typeof schema !== "undefined") {
|
$: if (typeof schema !== "undefined") {
|
||||||
|
@ -29,24 +30,22 @@
|
||||||
newCollections.length &&
|
newCollections.length &&
|
||||||
newCollections.length === newCollections.filter((item) => !!item.id && !!item.name).length;
|
newCollections.length === newCollections.filter((item) => !!item.id && !!item.name).length;
|
||||||
|
|
||||||
$: canImport = isValid && !isLoadingOldCollections;
|
|
||||||
|
|
||||||
$: collectionsToDelete = oldCollections.filter((collection) => {
|
$: collectionsToDelete = oldCollections.filter((collection) => {
|
||||||
return !CommonHelper.findByKey(newCollections, "id", collection.id);
|
return isValid && !CommonHelper.findByKey(newCollections, "id", collection.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
$: collectionsToAdd = newCollections.filter((collection) => {
|
$: collectionsToAdd = newCollections.filter((collection) => {
|
||||||
return !CommonHelper.findByKey(oldCollections, "id", collection.id);
|
return isValid && !CommonHelper.findByKey(oldCollections, "id", collection.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
$: collectionsToModify = newCollections.filter((newCollection) => {
|
$: if (typeof newCollections !== "undefined") {
|
||||||
const oldCollection = CommonHelper.findByKey(oldCollections, "id", newCollection.id);
|
loadCollectionsToModify();
|
||||||
if (!oldCollection?.id) {
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return JSON.stringify(oldCollection) !== JSON.stringify(newCollection);
|
$: hasChanges =
|
||||||
});
|
!!schema && (collectionsToDelete.length || collectionsToAdd.length || collectionsToModify.length);
|
||||||
|
|
||||||
|
$: canImport = !isLoadingOldCollections && isValid && hasChanges;
|
||||||
|
|
||||||
loadOldCollections();
|
loadOldCollections();
|
||||||
|
|
||||||
|
@ -54,9 +53,7 @@
|
||||||
isLoadingOldCollections = true;
|
isLoadingOldCollections = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
oldCollections = await ApiClient.collections.getFullList(100, {
|
oldCollections = await ApiClient.collections.getFullList(200);
|
||||||
$cancelKey: uniquePageId,
|
|
||||||
});
|
|
||||||
// delete timestamps
|
// delete timestamps
|
||||||
for (let collection of oldCollections) {
|
for (let collection of oldCollections) {
|
||||||
delete collection.created;
|
delete collection.created;
|
||||||
|
@ -69,6 +66,31 @@
|
||||||
isLoadingOldCollections = false;
|
isLoadingOldCollections = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadCollectionsToModify() {
|
||||||
|
collectionsToModify = [];
|
||||||
|
|
||||||
|
if (!isValid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let newCollection of newCollections) {
|
||||||
|
const oldCollection = CommonHelper.findByKey(oldCollections, "id", newCollection.id);
|
||||||
|
if (
|
||||||
|
// no old collection
|
||||||
|
!oldCollection?.id ||
|
||||||
|
// no changes
|
||||||
|
JSON.stringify(oldCollection) === JSON.stringify(newCollection)
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
collectionsToModify.push({
|
||||||
|
new: newCollection,
|
||||||
|
old: oldCollection,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function loadNewCollections() {
|
function loadNewCollections() {
|
||||||
newCollections = [];
|
newCollections = [];
|
||||||
|
|
||||||
|
@ -78,6 +100,8 @@
|
||||||
|
|
||||||
if (!Array.isArray(newCollections)) {
|
if (!Array.isArray(newCollections)) {
|
||||||
newCollections = [];
|
newCollections = [];
|
||||||
|
} else {
|
||||||
|
newCollections = CommonHelper.filterDuplicatesByKey(newCollections);
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete timestamps
|
// delete timestamps
|
||||||
|
@ -92,11 +116,18 @@
|
||||||
|
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
|
|
||||||
reader.onload = (event) => {
|
reader.onload = async (event) => {
|
||||||
schema = event.target.result;
|
|
||||||
|
|
||||||
isLoadingFile = false;
|
isLoadingFile = false;
|
||||||
fileInput.value = ""; // reset
|
fileInput.value = ""; // reset
|
||||||
|
|
||||||
|
schema = event.target.result;
|
||||||
|
|
||||||
|
await tick();
|
||||||
|
|
||||||
|
if (!newCollections.length) {
|
||||||
|
addErrorToast("Invalid collections schema.");
|
||||||
|
clear();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
reader.onerror = (err) => {
|
reader.onerror = (err) => {
|
||||||
|
@ -122,6 +153,11 @@
|
||||||
|
|
||||||
isImporting = false;
|
isImporting = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
schema = "";
|
||||||
|
fileInput.value = "";
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SettingsSidebar />
|
<SettingsSidebar />
|
||||||
|
@ -136,86 +172,146 @@
|
||||||
|
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="content txt-xl m-b-base">
|
{#if isLoadingOldCollections}
|
||||||
<input
|
<div class="loader" />
|
||||||
bind:this={fileInput}
|
{:else}
|
||||||
type="file"
|
<div class="content txt-xl m-b-base">
|
||||||
class="hidden"
|
<input
|
||||||
accept=".json"
|
bind:this={fileInput}
|
||||||
on:change={() => {
|
type="file"
|
||||||
if (fileInput.files.length) {
|
class="hidden"
|
||||||
loadFile(fileInput.files[0]);
|
accept=".json"
|
||||||
}
|
on:change={() => {
|
||||||
}}
|
if (fileInput.files.length) {
|
||||||
/>
|
loadFile(fileInput.files[0]);
|
||||||
|
}
|
||||||
<p>
|
|
||||||
Paste below the collections schema you want to import or
|
|
||||||
<button
|
|
||||||
class="btn btn-outline btn-sm"
|
|
||||||
class:btn-loading={isLoadingFile}
|
|
||||||
on:click={() => {
|
|
||||||
fileInput.click();
|
|
||||||
}}
|
}}
|
||||||
>
|
/>
|
||||||
<span class="txt">Import from JSON file</span>
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Field class="form-field {!isValid ? 'field-error' : ''}" name="collections" let:uniqueId>
|
<p>
|
||||||
<label for={uniqueId}>Collections schema</label>
|
Paste below the collections schema you want to import or
|
||||||
<textarea
|
<button
|
||||||
id={uniqueId}
|
class="btn btn-outline btn-sm m-l-5"
|
||||||
class="json-editor"
|
class:btn-loading={isLoadingFile}
|
||||||
spellcheck="false"
|
on:click={() => {
|
||||||
rows="20"
|
fileInput.click();
|
||||||
required
|
}}
|
||||||
bind:value={schema}
|
>
|
||||||
/>
|
<span class="txt">Load from JSON file</span>
|
||||||
{#if !!schema && !isValid}
|
</button>
|
||||||
<div class="help-block help-block-error">Invalid collections schema.</div>
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Field class="form-field {!isValid ? 'field-error' : ''}" name="collections" let:uniqueId>
|
||||||
|
<label for={uniqueId} class="p-b-10">Collections schema</label>
|
||||||
|
<textarea
|
||||||
|
id={uniqueId}
|
||||||
|
class="code"
|
||||||
|
spellcheck="false"
|
||||||
|
rows="15"
|
||||||
|
required
|
||||||
|
bind:value={schema}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{#if !!schema && !isValid}
|
||||||
|
<div class="help-block help-block-error">Invalid collections schema.</div>
|
||||||
|
{/if}
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
{#if isValid && newCollections.length && !hasChanges}
|
||||||
|
<div class="alert alert-info">
|
||||||
|
<div class="icon">
|
||||||
|
<i class="ri-information-line" />
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<string>Everything is up-to-date!</string>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</Field>
|
|
||||||
|
|
||||||
<div class="section-title">Detected changes</div>
|
{#if isValid && newCollections.length && hasChanges}
|
||||||
<p>No changes to your current collections schema were found.</p>
|
<div class="flex flex-gap-10">
|
||||||
|
<div>
|
||||||
|
<h5 class="section-title m-0">Detected changes</h5>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-sm btn-warning"
|
||||||
|
on:click={() => {
|
||||||
|
diffPopup?.show(
|
||||||
|
JSON.stringify(oldCollections, null, 2),
|
||||||
|
JSON.stringify(newCollections, null, 2)
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
View diff
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
{#each collectionsToDelete as collection (collection.id)}
|
<div class="list m-t-sm">
|
||||||
Delete {collection.name}
|
{#if collectionsToDelete.length}
|
||||||
<br />
|
{#each collectionsToDelete as collection (collection.id)}
|
||||||
{/each}
|
<div class="list-item">
|
||||||
|
<span class="label label-danger list-label">Deleted</span>
|
||||||
|
<strong>{collection.name}</strong>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#each collectionsToModify as collection (collection.id)}
|
{#if collectionsToModify.length}
|
||||||
Modify {collection.name}
|
{#each collectionsToModify as entry (entry.old.id + entry.new.id)}
|
||||||
<br />
|
<div class="list-item">
|
||||||
{/each}
|
<span class="label label-warning list-label">Modified</span>
|
||||||
|
<strong>
|
||||||
|
{#if entry.old.name !== entry.new.name}
|
||||||
|
<span class="txt-strikethrough txt-hint">{entry.old.name}</span> -
|
||||||
|
{/if}
|
||||||
|
{entry.new.name}
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
|
||||||
{#each collectionsToAdd as collection (collection.id)}
|
{#if collectionsToAdd.length}
|
||||||
Add {collection.name}
|
{#each collectionsToAdd as collection (collection.id)}
|
||||||
<br />
|
<div class="list-item">
|
||||||
{/each}
|
<span class="label label-success list-label">New</span>
|
||||||
|
<strong>{collection.name}</strong>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
<div class="flex m-t-base">
|
<div class="flex m-t-base">
|
||||||
<div class="flex-fill" />
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
class="btn btn-secondary link-hint"
|
||||||
class="btn btn-expanded"
|
disabled={!schema || isImporting}
|
||||||
class:btn-loading={isImporting}
|
on:click={() => clear()}
|
||||||
disabled={!canImport}
|
>
|
||||||
on:click={() => submitImport()}
|
<span class="txt">Clear</span>
|
||||||
>
|
</button>
|
||||||
<span class="txt">Import</span>
|
<div class="flex-fill" />
|
||||||
</button>
|
<button
|
||||||
</div>
|
type="button"
|
||||||
|
class="btn btn-expanded m-l-auto"
|
||||||
|
class:btn-loading={isImporting}
|
||||||
|
disabled={!canImport}
|
||||||
|
on:click={() => submitImport()}
|
||||||
|
>
|
||||||
|
<span class="txt">Import</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
<DiffPopup bind:this={diffPopup} />
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.json-editor {
|
.list-label {
|
||||||
font-size: 15px;
|
min-width: 65px;
|
||||||
line-height: 1.379rem;
|
|
||||||
font-family: var(--monospaceFontFamily);
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -64,11 +64,13 @@ em {
|
||||||
}
|
}
|
||||||
|
|
||||||
ins {
|
ins {
|
||||||
|
color: var(--txtPrimaryColor);
|
||||||
background: var(--successAltColor);
|
background: var(--successAltColor);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
del {
|
del {
|
||||||
|
color: var(--txtPrimaryColor);
|
||||||
background: var(--dangerAltColor);
|
background: var(--dangerAltColor);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
@ -129,6 +131,14 @@ code {
|
||||||
border-radius: var(--baseRadius);
|
border-radius: var(--baseRadius);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.code-block {
|
||||||
|
@extend %block;
|
||||||
|
overflow: auto;
|
||||||
|
padding: var(--xsSpacing);
|
||||||
|
white-space: pre-wrap;
|
||||||
|
background: var(--baseAlt1Color);
|
||||||
|
}
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
ul {
|
ul {
|
||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
|
@ -650,3 +660,23 @@ a,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
@extend %block;
|
||||||
|
position: relative;
|
||||||
|
border: 1px solid var(--baseAlt1Color);
|
||||||
|
border-radius: var(--baseRadius);
|
||||||
|
.list-item {
|
||||||
|
word-break: break-all;
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
gap: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border-bottom: 1px solid var(--baseAlt1Color);
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -353,6 +353,11 @@ button {
|
||||||
&.txt-mono {
|
&.txt-mono {
|
||||||
line-height: var(--smLineHeight);
|
line-height: var(--smLineHeight);
|
||||||
}
|
}
|
||||||
|
&.code {
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.379rem;
|
||||||
|
font-family: var(--monospaceFontFamily);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
input,
|
input,
|
||||||
|
@ -388,6 +393,13 @@ input[type=number]::-webkit-outer-spin-button {
|
||||||
textarea {
|
textarea {
|
||||||
min-height: 80px;
|
min-height: 80px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
|
&:focus,
|
||||||
|
&:focus-within {
|
||||||
|
@include scrollbar(
|
||||||
|
$thumbColor: var(--baseAlt3Color),
|
||||||
|
$thumbActiveColor: var(--baseAlt4Color)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
|
@ -1025,5 +1037,8 @@ select {
|
||||||
font-size: var(--baseFontSize);
|
font-size: var(--baseFontSize);
|
||||||
line-height: var(--baseLineHeight);
|
line-height: var(--baseLineHeight);
|
||||||
}
|
}
|
||||||
|
.cm-selectionMatch {
|
||||||
|
background: var(--infoAltColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,40 +12,46 @@
|
||||||
box-shadow: 0px 2px 5px 0px var(--shadowColor), $value;
|
box-shadow: 0px 2px 5px 0px var(--shadowColor), $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin scrollbar($width: 8px) {
|
@mixin scrollbar(
|
||||||
|
$width: 8px,
|
||||||
|
$thumbColor: var(--baseAlt2Color),
|
||||||
|
$thumbActiveColor: var(--baseAlt3Color)
|
||||||
|
) {
|
||||||
$trackColor: transparent;
|
$trackColor: transparent;
|
||||||
|
|
||||||
|
$elem: if(&, '&', '');
|
||||||
|
|
||||||
@media screen and (min-width: 550px) {
|
@media screen and (min-width: 550px) {
|
||||||
// chrome scrollbar styles
|
// chrome scrollbar styles
|
||||||
::-webkit-scrollbar {
|
#{$elem}::-webkit-scrollbar {
|
||||||
width: $width;
|
width: $width;
|
||||||
height: $width;
|
height: $width;
|
||||||
border-radius: var(--baseRadius);
|
border-radius: var(--baseRadius);
|
||||||
}
|
}
|
||||||
::-webkit-scrollbar-track {
|
#{$elem}::-webkit-scrollbar-track {
|
||||||
background: $trackColor;
|
background: $trackColor;
|
||||||
border-radius: var(--baseRadius);
|
border-radius: var(--baseRadius);
|
||||||
}
|
}
|
||||||
::-webkit-scrollbar-thumb {
|
#{$elem}::-webkit-scrollbar-thumb {
|
||||||
background-color: var(--baseAlt2Color);
|
background-color: $thumbColor;
|
||||||
border-radius: 15px;
|
border-radius: 15px;
|
||||||
border: 2px solid transparent;
|
border: 2px solid transparent;
|
||||||
background-clip: padding-box;
|
background-clip: padding-box;
|
||||||
&:hover,
|
&:hover,
|
||||||
&:active {
|
&:active {
|
||||||
background-color: var(--baseAlt3Color);
|
background-color: $thumbActiveColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@if & {
|
@if & {
|
||||||
// firefox scrollbar
|
// firefox scrollbar
|
||||||
scrollbar-color: var(--baseAlt2Color) $trackColor;
|
scrollbar-color: $thumbColor $trackColor;
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
} @else {
|
} @else {
|
||||||
html {
|
html {
|
||||||
// firefox scrollbar
|
// firefox scrollbar
|
||||||
scrollbar-color: var(--baseAlt2Color) $trackColor;
|
scrollbar-color: $thumbColor $trackColor;
|
||||||
scrollbar-width: thin;
|
scrollbar-width: thin;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
|
|
||||||
|
|
|
@ -193,6 +193,9 @@
|
||||||
row-gap: var(--smSpacing);
|
row-gap: var(--smSpacing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.full-width-popup {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
&.image-preview {
|
&.image-preview {
|
||||||
width: auto;
|
width: auto;
|
||||||
min-width: 300px;
|
min-width: 300px;
|
||||||
|
|
Loading…
Reference in New Issue