chore(frontend): introduce prettier + eslint and prune unused code
- Add Prettier 3 with prettier-plugin-organize-imports (sorts/removes unused imports) - Add ESLint 10 flat config with typescript-eslint + eslint-plugin-vue + eslint-config-prettier - Add root scripts: format, format:check, lint, lint:fix - Reformat 257 files across admin-web, ops-web, desktop-client, packages - Remove unused locals/exports flagged by --noUnusedLocals/--noUnusedParameters - Fix duplicate localTabLabel key, surrogate-pair regex u-flag, NBSP literal in regex - Skip server/ (Go) and apps/browser-extension/ (deprecated per ADR) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,60 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
import { InfoCircleOutlined } from "@ant-design/icons-vue";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
|
||||
import { message } from "ant-design-vue";
|
||||
import type { PromptRule, PromptRuleGroup } from "@geo/shared-types";
|
||||
import { computed, reactive, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { InfoCircleOutlined } from '@ant-design/icons-vue'
|
||||
import type { PromptRule, PromptRuleGroup } from '@geo/shared-types'
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { message } from 'ant-design-vue'
|
||||
import { computed, reactive, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import KnowledgeGroupSelect from "@/components/KnowledgeGroupSelect.vue";
|
||||
import { promptRulesApi } from "@/lib/api";
|
||||
import { formatError } from "@/lib/errors";
|
||||
import KnowledgeGroupSelect from '@/components/KnowledgeGroupSelect.vue'
|
||||
import { promptRulesApi } from '@/lib/api'
|
||||
import { formatError } from '@/lib/errors'
|
||||
|
||||
const props = defineProps<{
|
||||
open: boolean;
|
||||
rule?: PromptRule | null;
|
||||
}>();
|
||||
open: boolean
|
||||
rule?: PromptRule | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
"update:open": [value: boolean];
|
||||
saved: [ruleId: number];
|
||||
}>();
|
||||
'update:open': [value: boolean]
|
||||
saved: [ruleId: number]
|
||||
}>()
|
||||
|
||||
const queryClient = useQueryClient();
|
||||
const { t } = useI18n();
|
||||
const queryClient = useQueryClient()
|
||||
const { t } = useI18n()
|
||||
|
||||
const form = reactive({
|
||||
name: "",
|
||||
prompt_content: "",
|
||||
scene: "",
|
||||
default_tone: "",
|
||||
name: '',
|
||||
prompt_content: '',
|
||||
scene: '',
|
||||
default_tone: '',
|
||||
default_word_count: undefined as number | undefined,
|
||||
group_id: undefined as number | undefined,
|
||||
knowledge_group_ids: [] as number[],
|
||||
});
|
||||
})
|
||||
|
||||
const groupsQuery = useQuery({
|
||||
queryKey: ["promptRules", "groups"],
|
||||
queryKey: ['promptRules', 'groups'],
|
||||
queryFn: () => promptRulesApi.listGroups(),
|
||||
});
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.open,
|
||||
(open) => {
|
||||
if (!open) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
const rule = props.rule;
|
||||
form.name = rule?.name ?? "";
|
||||
form.prompt_content = rule?.prompt_content ?? "";
|
||||
form.scene = rule?.scene ?? "";
|
||||
form.default_tone = rule?.default_tone ?? "";
|
||||
form.default_word_count = rule?.default_word_count ?? undefined;
|
||||
form.group_id = rule?.group_id ?? undefined;
|
||||
form.knowledge_group_ids = rule?.knowledge_group_ids ?? [];
|
||||
const rule = props.rule
|
||||
form.name = rule?.name ?? ''
|
||||
form.prompt_content = rule?.prompt_content ?? ''
|
||||
form.scene = rule?.scene ?? ''
|
||||
form.default_tone = rule?.default_tone ?? ''
|
||||
form.default_word_count = rule?.default_word_count ?? undefined
|
||||
form.group_id = rule?.group_id ?? undefined
|
||||
form.knowledge_group_ids = rule?.knowledge_group_ids ?? []
|
||||
},
|
||||
);
|
||||
)
|
||||
|
||||
const createMutation = useMutation({
|
||||
mutationFn: () =>
|
||||
@@ -68,13 +68,13 @@ const createMutation = useMutation({
|
||||
knowledge_group_ids: form.knowledge_group_ids,
|
||||
}),
|
||||
onSuccess: async (data) => {
|
||||
message.success(t("custom.messages.ruleCreated"));
|
||||
emit("saved", data.id);
|
||||
emit("update:open", false);
|
||||
await queryClient.invalidateQueries({ queryKey: ["promptRules"] });
|
||||
message.success(t('custom.messages.ruleCreated'))
|
||||
emit('saved', data.id)
|
||||
emit('update:open', false)
|
||||
await queryClient.invalidateQueries({ queryKey: ['promptRules'] })
|
||||
},
|
||||
onError: (error) => message.error(formatError(error)),
|
||||
});
|
||||
})
|
||||
|
||||
const updateMutation = useMutation({
|
||||
mutationFn: () =>
|
||||
@@ -88,41 +88,41 @@ const updateMutation = useMutation({
|
||||
knowledge_group_ids: form.knowledge_group_ids,
|
||||
}),
|
||||
onSuccess: async () => {
|
||||
message.success(t("custom.messages.ruleUpdated"));
|
||||
message.success(t('custom.messages.ruleUpdated'))
|
||||
if (props.rule?.id) {
|
||||
emit("saved", props.rule.id);
|
||||
emit('saved', props.rule.id)
|
||||
}
|
||||
emit("update:open", false);
|
||||
await queryClient.invalidateQueries({ queryKey: ["promptRules"] });
|
||||
emit('update:open', false)
|
||||
await queryClient.invalidateQueries({ queryKey: ['promptRules'] })
|
||||
},
|
||||
onError: (error) => message.error(formatError(error)),
|
||||
});
|
||||
})
|
||||
|
||||
const submitLoading = computed(
|
||||
() => createMutation.isPending.value || updateMutation.isPending.value,
|
||||
);
|
||||
)
|
||||
|
||||
const drawerTitle = computed(() =>
|
||||
props.rule?.id ? t("custom.promptRule.editTitle") : t("custom.promptRule.createTitle"),
|
||||
);
|
||||
props.rule?.id ? t('custom.promptRule.editTitle') : t('custom.promptRule.createTitle'),
|
||||
)
|
||||
|
||||
async function handleSubmit(): Promise<void> {
|
||||
if (!form.name.trim()) {
|
||||
message.warning(t("custom.messages.missingPromptName"));
|
||||
return;
|
||||
message.warning(t('custom.messages.missingPromptName'))
|
||||
return
|
||||
}
|
||||
|
||||
if (!form.prompt_content.trim()) {
|
||||
message.warning(t("custom.messages.missingPromptContent"));
|
||||
return;
|
||||
message.warning(t('custom.messages.missingPromptContent'))
|
||||
return
|
||||
}
|
||||
|
||||
if (props.rule?.id) {
|
||||
await updateMutation.mutateAsync();
|
||||
return;
|
||||
await updateMutation.mutateAsync()
|
||||
return
|
||||
}
|
||||
|
||||
await createMutation.mutateAsync();
|
||||
await createMutation.mutateAsync()
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -139,7 +139,7 @@ async function handleSubmit(): Promise<void> {
|
||||
<div class="prompt-rule-drawer__body">
|
||||
<div class="prompt-rule-drawer__field">
|
||||
<label class="prompt-rule-drawer__label prompt-rule-drawer__label--required">
|
||||
{{ t("custom.promptRule.name") }}:
|
||||
{{ t('custom.promptRule.name') }}:
|
||||
</label>
|
||||
<a-input
|
||||
v-model:value="form.name"
|
||||
@@ -151,7 +151,7 @@ async function handleSubmit(): Promise<void> {
|
||||
|
||||
<div class="prompt-rule-drawer__field">
|
||||
<label class="prompt-rule-drawer__label prompt-rule-drawer__label--required">
|
||||
{{ t("custom.promptRule.content") }}:
|
||||
{{ t('custom.promptRule.content') }}:
|
||||
</label>
|
||||
<a-textarea
|
||||
v-model:value="form.prompt_content"
|
||||
@@ -161,34 +161,36 @@ async function handleSubmit(): Promise<void> {
|
||||
</div>
|
||||
|
||||
<div class="prompt-rule-drawer__field">
|
||||
<label class="prompt-rule-drawer__label">{{ t("custom.group.title") }}:</label>
|
||||
<label class="prompt-rule-drawer__label">{{ t('custom.group.title') }}:</label>
|
||||
<a-select
|
||||
v-model:value="form.group_id"
|
||||
size="large"
|
||||
style="width: 100%"
|
||||
:placeholder="t('custom.promptRule.groupPlaceholder')"
|
||||
:options="(groupsQuery.data.value ?? []).map((group: PromptRuleGroup) => ({
|
||||
label: group.name,
|
||||
value: group.id,
|
||||
}))"
|
||||
:options="
|
||||
(groupsQuery.data.value ?? []).map((group: PromptRuleGroup) => ({
|
||||
label: group.name,
|
||||
value: group.id,
|
||||
}))
|
||||
"
|
||||
allow-clear
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="prompt-rule-drawer__grid">
|
||||
<div class="prompt-rule-drawer__field">
|
||||
<label class="prompt-rule-drawer__label">{{ t("custom.promptRule.scene") }}:</label>
|
||||
<label class="prompt-rule-drawer__label">{{ t('custom.promptRule.scene') }}:</label>
|
||||
<a-input v-model:value="form.scene" size="large" />
|
||||
</div>
|
||||
|
||||
<div class="prompt-rule-drawer__field">
|
||||
<label class="prompt-rule-drawer__label">{{ t("custom.promptRule.tone") }}:</label>
|
||||
<label class="prompt-rule-drawer__label">{{ t('custom.promptRule.tone') }}:</label>
|
||||
<a-input v-model:value="form.default_tone" size="large" />
|
||||
</div>
|
||||
|
||||
<div class="prompt-rule-drawer__field">
|
||||
<label class="prompt-rule-drawer__label">
|
||||
{{ t("custom.promptRule.wordCount") }}:
|
||||
{{ t('custom.promptRule.wordCount') }}:
|
||||
<a-tooltip :title="t('custom.promptRule.wordCountHint')">
|
||||
<InfoCircleOutlined style="margin-left: 6px; color: #8c8c8c; cursor: help" />
|
||||
</a-tooltip>
|
||||
@@ -215,10 +217,10 @@ async function handleSubmit(): Promise<void> {
|
||||
<template #footer>
|
||||
<div class="prompt-rule-drawer__footer">
|
||||
<a-button size="large" @click="emit('update:open', false)">
|
||||
{{ t("common.cancel") }}
|
||||
{{ t('common.cancel') }}
|
||||
</a-button>
|
||||
<a-button type="primary" size="large" :loading="submitLoading" @click="handleSubmit">
|
||||
{{ t("common.confirm") }}
|
||||
{{ t('common.confirm') }}
|
||||
</a-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -283,7 +285,7 @@ async function handleSubmit(): Promise<void> {
|
||||
}
|
||||
|
||||
.prompt-rule-drawer__label--required::before {
|
||||
content: "*";
|
||||
content: '*';
|
||||
margin-right: 4px;
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user