diff --git a/app/components/editor/hooks/useIndex.tsx b/app/components/editor/hooks/useIndex.tsx
index a49aff5..586260b 100644
--- a/app/components/editor/hooks/useIndex.tsx
+++ b/app/components/editor/hooks/useIndex.tsx
@@ -44,7 +44,7 @@ export default function useIndex() {
const hash = window.location.hash.slice(1);
if (hash && hash !== loadState.current.loadedHash) {
loadState.current.loadedHash = hash;
- setEcho(
Loading Shared Content...
);
+ setEcho(Loading Shared Content...
);
fetch(`https://dpaste.com/${hash}.txt`)
.then((resp) => {
return resp.ok ? resp.text() : Promise.reject(`HTTP error: ${resp.status}`);
@@ -54,10 +54,10 @@ export default function useIndex() {
loadState.current.content = parsed;
const newModelKind = parsed?.modelKind && parsed.modelKind in example ? (parsed.modelKind as ModelKind) : 'basic';
setModelKind(newModelKind);
- setEcho(Shared Content Loaded.
);
+ setEcho(Shared Content Loaded.
);
})
.catch((error) => {
- return setEcho(Failed to load: {error}
);
+ return setEcho(Failed to load: {error}
);
});
}
}, []);
@@ -79,7 +79,7 @@ export default function useIndex() {
} else {
const currentPath = window.location.origin + window.location.pathname;
setShare(v as string);
- setEcho({`Shared at ${currentPath}#${v}`}
);
+ setEcho({`Shared at ${currentPath}#${v}`}
);
}
}
diff --git a/app/components/editor/hooks/useRunTest.tsx b/app/components/editor/hooks/useRunTest.tsx
index 60e2542..1a9bab3 100755
--- a/app/components/editor/hooks/useRunTest.tsx
+++ b/app/components/editor/hooks/useRunTest.tsx
@@ -181,11 +181,11 @@ async function enforcer(props: RunTestProps) {
setError(null);
- props.onResponse({'Done in ' + (stopTime - startTime).toFixed(2) + 'ms'}
);
+ props.onResponse({'Done in ' + (stopTime - startTime).toFixed(2) + 'ms'}
);
props.onResponse(result);
} catch (e) {
const errorMessage = (e as any).message;
- props.onResponse({errorMessage}
);
+ props.onResponse({errorMessage}
);
props.onResponse([]);
setError(errorMessage);
}
diff --git a/app/components/editor/hooks/useShareInfo.tsx b/app/components/editor/hooks/useShareInfo.tsx
index d2aa692..6f782e5 100644
--- a/app/components/editor/hooks/useShareInfo.tsx
+++ b/app/components/editor/hooks/useShareInfo.tsx
@@ -42,7 +42,7 @@ export default function useShareInfo() {
function shareInfo(props: ShareProps) {
if (sharing) return;
setSharing(true);
- props.onResponse(Sharing...
);
+ props.onResponse(Sharing...
);
// Create an object that contains only non-null values
const shareContent: ShareFormat = {
@@ -58,7 +58,7 @@ export default function useShareInfo() {
// Check if there are any non-null values to share
if (Object.keys(shareContent).length === 0) {
setSharing(false);
- props.onResponse(No content to share
);
+ props.onResponse(No content to share
);
return;
}
@@ -70,7 +70,7 @@ export default function useShareInfo() {
})
.catch((error) => {
setSharing(false);
- props.onResponse(Error sharing content: {error.message}
);
+ props.onResponse(Error sharing content: {error.message}
);
});
}
diff --git a/app/components/editor/index.tsx b/app/components/editor/index.tsx
index c82405c..cdc3064 100755
--- a/app/components/editor/index.tsx
+++ b/app/components/editor/index.tsx
@@ -11,7 +11,6 @@ import { go } from '@codemirror/legacy-modes/mode/go';
import { EditorView } from '@codemirror/view';
import { CasbinConfSupport } from '@/app/components/editor/casbin-mode/casbin-conf';
import { CasbinPolicySupport } from '@/app/components/editor/casbin-mode/casbin-csv';
-import { Config } from 'casbin';
import { javascriptLanguage } from '@codemirror/lang-javascript';
import useRunTest from '@/app/components/editor/hooks/useRunTest';
import useShareInfo from '@/app/components/editor/hooks/useShareInfo';
@@ -25,6 +24,7 @@ import { useLang } from '@/app/context/LangContext';
import LanguageMenu from '@/app/components/LanguageMenu';
import { linter, lintGutter } from '@codemirror/lint';
import { casbinLinter } from '@/app/utils/casbinLinter';
+import { toast, Toaster } from 'react-hot-toast';
export const EditorScreen = () => {
const {
@@ -54,6 +54,7 @@ export const EditorScreen = () => {
return message;
};
const { t, lang, theme, toggleTheme } = useLang();
+ const [isContentLoaded, setIsContentLoaded] = useState(false);
useEffect(() => {
const fetchCasbinVersion = async () => {
@@ -65,7 +66,8 @@ export const EditorScreen = () => {
}, []);
useEffect(() => {
- if (modelKind) {
+ if (modelKind && modelText) {
+ setIsContentLoaded(true);
enforcer({
modelKind,
model: modelText,
@@ -94,6 +96,7 @@ export const EditorScreen = () => {
return (
+
{
-
{
- try {
- Config.newConfigFromText(modelText);
- setEcho(Passed
);
- } catch (e) {
- setEcho({(e as any).message}
);
- }
- }}
- >
- {t('SYNTAX VALIDATE')}
-
{
customConfig,
request,
enforceContextData,
- onResponse: (v) => {
+ onResponse: (v: JSX.Element | any[]) => {
if (isValidElement(v)) {
setEcho(v);
+ const props = (v as any).props;
+ if (props.className?.includes('text-red-500')) {
+ const errorMessage = props.children;
+ toast.error(errorMessage);
+ setRequestResult(errorMessage);
+ }
} else if (Array.isArray(v)) {
const formattedResults = v.map((res) => {
if (typeof res === 'object') {
- const reasonString = Array.isArray(res.reason) && res.reason.length > 0 ? ` Reason: ${JSON.stringify(res.reason)}` : '';
+ const reasonString = Array.isArray(res.reason) && res.reason.length > 0
+ ? ` Reason: ${JSON.stringify(res.reason)}`
+ : '';
return `${res.okEx}${reasonString}`;
}
return res;
});
- setRequestResult(formattedResults.join('\n'));
+ const result = formattedResults.join('\n');
+ setRequestResult(result);
+ if (result && !result.includes('error')) {
+ toast.success('Test completed successfully');
+ }
}
},
});
@@ -488,7 +482,8 @@ export const EditorScreen = () => {
return copy(
() => {
setShare('');
- setEcho({t('Copied')}
);
+ setEcho({t('Copied')}
);
+ toast.success(t('Link copied to clipboard'));
},
`${window.location.origin + window.location.pathname}#${share}`,
);
diff --git a/app/utils/contentExtractor.ts b/app/utils/contentExtractor.ts
index 5a5c622..3555284 100644
--- a/app/utils/contentExtractor.ts
+++ b/app/utils/contentExtractor.ts
@@ -12,7 +12,7 @@ export const extractPageContent = (boxType: string, t: (key: string) => string,
const modelMatch = mainContent.match(new RegExp(`${t('Model')}\\s+([\\s\\S]*?)\\s+${t('Policy')}`));
const policyMatch = mainContent.match(new RegExp(`${t('Policy')}\\s+([\\s\\S]*?)\\s+${t('Request')}`));
const requestMatch = mainContent.match(new RegExp(`${t('Request')}\\s+([\\s\\S]*?)\\s+${t('Enforcement Result')}`));
- const enforcementResultMatch = mainContent.match(new RegExp(`${t('Enforcement Result')}\\s+([\\s\\S]*?)\\s+${t('SYNTAX VALIDATE')}`));
+ const enforcementResultMatch = mainContent.match(new RegExp(`${t('Enforcement Result')}\\s+([\\s\\S]*?)\\s+${t('RUN THE TEST')}`));
const customConfig = customConfigMatch ? cleanContent(customConfigMatch[1]) : 'No custom config found';
const model = modelMatch
diff --git a/messages/ar.json b/messages/ar.json
index 37bc62b..3bb3225 100644
--- a/messages/ar.json
+++ b/messages/ar.json
@@ -7,7 +7,6 @@
"Request": "طلب",
"Enforcement Result": "نتيجة التنفيذ",
"Why this result": "لماذا هذه النتيجة",
- "SYNTAX VALIDATE": "التحقق من بناء الجملة",
"RUN THE TEST": "تشغيل الاختبار",
"SHARE": "مشاركة",
"Copied": "تم النسخ",
diff --git a/messages/de.json b/messages/de.json
index 972ab8b..b2e3a5c 100644
--- a/messages/de.json
+++ b/messages/de.json
@@ -7,7 +7,6 @@
"Request": "Anfrage",
"Enforcement Result": "Durchsetzungsergebnis",
"Why this result": "Warum dieses Ergebnis?",
- "SYNTAX VALIDATE": "Syntax validieren",
"RUN THE TEST": "Test ausführen",
"SHARE": "Teilen",
"Copied": "Kopiert",
diff --git a/messages/en.json b/messages/en.json
index 9e2cd0a..c7d101e 100644
--- a/messages/en.json
+++ b/messages/en.json
@@ -7,7 +7,6 @@
"Request": "Request",
"Enforcement Result": "Enforcement Result",
"Why this result": "Why this result",
- "SYNTAX VALIDATE": "SYNTAX VALIDATE",
"RUN THE TEST": "RUN THE TEST",
"SHARE": "SHARE",
"Copied": "Copied",
diff --git a/messages/es.json b/messages/es.json
index 29d5308..2d760ac 100644
--- a/messages/es.json
+++ b/messages/es.json
@@ -7,7 +7,6 @@
"Request": "Solicitud",
"Enforcement Result": "Resultado de ejecución",
"Why this result": "Por qué este resultado",
- "SYNTAX VALIDATE": "VALIDAR SINTAXIS",
"RUN THE TEST": "EJECUTAR PRUEBA",
"SHARE": "COMPARTIR",
"Copied": "Copiado",
diff --git a/messages/fr.json b/messages/fr.json
index c01250f..0b10ac8 100644
--- a/messages/fr.json
+++ b/messages/fr.json
@@ -7,7 +7,6 @@
"Request": "Requête",
"Enforcement Result": "Résultat d'application",
"Why this result": "Pourquoi ce résultat ?",
- "SYNTAX VALIDATE": "Valider la syntaxe",
"RUN THE TEST": "Exécuter le test",
"SHARE": "Partager",
"Copied": "Copié",
diff --git a/messages/id.json b/messages/id.json
index d00c8aa..0aa1557 100644
--- a/messages/id.json
+++ b/messages/id.json
@@ -7,7 +7,6 @@
"Request": "Permintaan",
"Enforcement Result": "Hasil penegakan",
"Why this result": "Mengapa hasil ini",
- "SYNTAX VALIDATE": "VALIDASI SINTAKS",
"RUN THE TEST": "JALANKAN UJI",
"SHARE": "BAGIKAN",
"Copied": "Tersalin",
diff --git a/messages/it.json b/messages/it.json
index 6db3309..5d22da6 100644
--- a/messages/it.json
+++ b/messages/it.json
@@ -7,7 +7,6 @@
"Request": "Richiesta",
"Enforcement Result": "Risultato dell'applicazione",
"Why this result": "Perché questo risultato",
- "SYNTAX VALIDATE": "VALIDARE LA SINTASSI",
"RUN THE TEST": "ESEGUI IL TEST",
"SHARE": "CONDIVIDI",
"Copied": "Copiato",
diff --git a/messages/ja.json b/messages/ja.json
index 9ced945..d99eeb1 100644
--- a/messages/ja.json
+++ b/messages/ja.json
@@ -7,7 +7,6 @@
"Request": "リクエスト",
"Enforcement Result": "実行結果",
"Why this result": "なぜこの結果?",
- "SYNTAX VALIDATE": "構文検証",
"RUN THE TEST": "テスト実行",
"SHARE": "共有",
"Copied": "コピー完了",
diff --git a/messages/ko.json b/messages/ko.json
index b4b794c..2e358ed 100644
--- a/messages/ko.json
+++ b/messages/ko.json
@@ -7,7 +7,6 @@
"Request": "요청",
"Enforcement Result": "집행 결과",
"Why this result": "이 결과의 이유",
- "SYNTAX VALIDATE": "구문 유효성 검사",
"RUN THE TEST": "테스트 실행",
"SHARE": "공유",
"Copied": "복사됨",
diff --git a/messages/ms.json b/messages/ms.json
index b76bed1..2a4c8b9 100644
--- a/messages/ms.json
+++ b/messages/ms.json
@@ -7,7 +7,6 @@
"Request": "Permintaan",
"Enforcement Result": "Keputusan penguatkuasaan",
"Why this result": "Mengapa keputusan ini",
- "SYNTAX VALIDATE": "SAH KAN SINTAKS",
"RUN THE TEST": "JALANKAN UJIAN",
"SHARE": "KONGSI",
"Copied": "Disalin",
diff --git a/messages/pt.json b/messages/pt.json
index e14ebc2..2dca6e6 100644
--- a/messages/pt.json
+++ b/messages/pt.json
@@ -7,7 +7,6 @@
"Request": "Solicitação",
"Enforcement Result": "Resultado da aplicação",
"Why this result": "Por que esse resultado",
- "SYNTAX VALIDATE": "VALIDAR SINTAXE",
"RUN THE TEST": "EXECUTAR TESTE",
"SHARE": "COMPARTILHAR",
"Copied": "Copiado",
diff --git a/messages/ru.json b/messages/ru.json
index 221ca9e..3deae5e 100644
--- a/messages/ru.json
+++ b/messages/ru.json
@@ -7,7 +7,6 @@
"Request": "Запрос",
"Enforcement Result": "Результат исполнения",
"Why this result": "Почему этот результат",
- "SYNTAX VALIDATE": "ПРОВЕРКА СИНТАКСИСА",
"RUN THE TEST": "ЗАПУСТИТЬ ТЕСТ",
"SHARE": "ПОДЕЛИТЬСЯ",
"Copied": "Скопировано",
diff --git a/messages/tr.json b/messages/tr.json
index 6303c89..d982d2b 100644
--- a/messages/tr.json
+++ b/messages/tr.json
@@ -7,7 +7,6 @@
"Request": "İstek",
"Enforcement Result": "Uygulama Sonucu",
"Why this result": "Neden bu sonuç",
- "SYNTAX VALIDATE": "SÖZDİZİMİ DOĞRULAMA",
"RUN THE TEST": "TESTİ ÇALIŞTIR",
"SHARE": "PAYLAŞ",
"Copied": "Kopyalandı",
diff --git a/messages/vi.json b/messages/vi.json
index 6df92b6..f59241d 100644
--- a/messages/vi.json
+++ b/messages/vi.json
@@ -7,7 +7,6 @@
"Request": "Yêu cầu",
"Enforcement Result": "Kết quả thi hành",
"Why this result": "Tại sao kết quả này",
- "SYNTAX VALIDATE": "KIỂM TRA CÚ PHÁP",
"RUN THE TEST": "CHẠY THỬ",
"SHARE": "CHIA SẺ",
"Copied": "Đã sao chép",
diff --git a/messages/zh-Hant.json b/messages/zh-Hant.json
index 391275e..444f226 100644
--- a/messages/zh-Hant.json
+++ b/messages/zh-Hant.json
@@ -7,7 +7,6 @@
"Request": "請求",
"Enforcement Result": "執行結果",
"Why this result": "為何此結果?",
- "SYNTAX VALIDATE": "驗證語法",
"RUN THE TEST": "運行",
"SHARE": "分享",
"Copied": "已複製",
diff --git a/messages/zh.json b/messages/zh.json
index 91d8c3a..6775eaa 100644
--- a/messages/zh.json
+++ b/messages/zh.json
@@ -7,7 +7,6 @@
"Request": "请求",
"Enforcement Result": "执行结果",
"Why this result": "为何此结果?",
- "SYNTAX VALIDATE": "验证语法",
"RUN THE TEST": "运行",
"SHARE": "分享",
"Copied": "已复制",
diff --git a/package.json b/package.json
index 5cdfc2b..56f2c4b 100644
--- a/package.json
+++ b/package.json
@@ -91,7 +91,8 @@
"codemirror": "^6.0.1",
"next": "14.1.0",
"react": "^18",
- "react-dom": "^18"
+ "react-dom": "^18",
+ "react-hot-toast": "^2.4.1"
},
"devDependencies": {
"@types/node": "^20",
diff --git a/yarn.lock b/yarn.lock
index b30f9e6..b59572b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1357,9 +1357,9 @@ camelcase-css@^2.0.1:
integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
caniuse-lite@^1.0.30001579, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001599:
- version "1.0.30001621"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001621.tgz#4adcb443c8b9c8303e04498318f987616b8fea2e"
- integrity sha512-+NLXZiviFFKX0fk8Piwv3PfLPGtRqJeq2TiNoUff/qB5KJgwecJTvCXDpmlyP/eCI/GUEmp/h/y5j0yckiiZrA==
+ version "1.0.30001684"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001684.tgz"
+ integrity sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==
casbin@^5.36.0:
version "5.36.0"
@@ -2477,6 +2477,11 @@ globby@^11.1.0:
merge2 "^1.4.1"
slash "^3.0.0"
+goober@^2.1.10:
+ version "2.1.16"
+ resolved "https://registry.yarnpkg.com/goober/-/goober-2.1.16.tgz#7d548eb9b83ff0988d102be71f271ca8f9c82a95"
+ integrity sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==
+
gopd@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
@@ -3584,6 +3589,13 @@ react-dom@^18:
loose-envify "^1.1.0"
scheduler "^0.23.2"
+react-hot-toast@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/react-hot-toast/-/react-hot-toast-2.4.1.tgz#df04295eda8a7b12c4f968e54a61c8d36f4c0994"
+ integrity sha512-j8z+cQbWIM5LY37pR6uZR6D4LfseplqnuAO4co4u8917hBUvXlEqyP1ZzqVLcqoyUesZZv/ImreoCeHVDpE5pQ==
+ dependencies:
+ goober "^2.1.10"
+
react-is@^16.13.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"