-
Notifications
You must be signed in to change notification settings - Fork 5
feat: add "My" footer tab and personal page with six blocks #76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
c4627ad
9b9fe74
d6c2c7b
2c188b9
2b0847e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| --- | ||
| on: | ||
| issues: | ||
| types: [opened] | ||
| permissions: | ||
| issues: read | ||
| contents: read | ||
|
|
||
| safe-outputs: | ||
| update-issue: | ||
| max: 1 | ||
|
|
||
| engine: | ||
| id: copilot | ||
| env: | ||
| COPILOT_PROVIDER_BASE_URL: "https://api.deepseek.com/v1" | ||
| COPILOT_PROVIDER_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} | ||
| COPILOT_MODEL: "deepseek/deepseek-chat" | ||
| COPILOT_GITHUB_TOKEN: ${{ secrets.DEEPSEEK_API_KEY }} | ||
| --- | ||
|
|
||
| # Issue auto-translation workflow | ||
|
|
||
| You are a community multilingual maintenance assistant. Your sole responsibility is to ensure that all non-English submitted Issues are translated into English for the convenience of global maintainers. | ||
|
|
||
| ## Task Description | ||
|
|
||
| 1. **Load the Issue and Produce a Safe Output:** | ||
| - First read the current Issue title and body for the issue number provided in the GitHub context. | ||
| - You **must finish every successful run by calling exactly one safe-output tool**: either `update_issue` when a translation is needed or `noop` when no visible update is needed. | ||
| - Do not end the run with a plain-text explanation only. Safe outputs are mandatory so the workflow can complete cleanly. | ||
|
|
||
| 2. **Language Detection and Skip Conditions:** | ||
| - Check if the Issue body contains `[AI Translation]`. If it does, it means it has already been translated, and you **must call the `noop` safe-output tool and end immediately** to prevent an infinite loop. | ||
| - If you detect that both the Issue title and body are already in pure English, **call the `noop` safe-output tool** and end without taking any visible action. | ||
|
|
||
| 3. **Perform Translation:** | ||
| - If you detect that the title or body contains non-English languages, please translate it completely and accurately into professional frontend technical English. | ||
| - At the top of the translated English body, you must retain this header: | ||
| `> **[AI Translation]** This issue has been automatically translated from its original language to English.` | ||
| - After the translation is complete, retain the original text at the end and add the header: | ||
| `> **[Original Issue]** The original issue content is provided below for reference:` | ||
|
|
||
| 4. **Update the Issue:** | ||
| - Use your built-in `update_issue` safe-output tool to overwrite the original Issue's title and body with the translated English content. | ||
| - Include the issue number from the GitHub context when calling `update_issue`. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,121 @@ | ||
| <template> | ||
| <div id="my-page"> | ||
| <Header> | ||
| <div class="my-page__title">{{ $t('footer.my') }}</div> | ||
| </Header> | ||
| <main> | ||
| <div v-show="isLoading" class="loading"></div> | ||
| <div v-show="!isLoading" class="block-container"> | ||
| <n-grid :x-gap="12" :y-gap="12" :cols="blockItemsPerRow"> | ||
| <n-gi v-for="block in blocks" :key="block.Header"> | ||
| <div class="my-page__block"> | ||
| <Block :block="block" :maxProjectsPerBlock="maxProjectsPerBlock" /> | ||
| </div> | ||
| </n-gi> | ||
| </n-grid> | ||
| </div> | ||
| </main> | ||
| </div> | ||
| <Footer></Footer> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| import { ref, onMounted } from 'vue' | ||
| import { NGrid, NGi } from 'naive-ui' | ||
| import { useI18n } from 'vue-i18n' | ||
| import { getData } from '@api/getData' | ||
| import { checkLogin } from '@services/utils' | ||
| import { showLoginModel } from '@popup/index' | ||
| import { useResponsive } from '../layout/useResponsive' | ||
| import Header from '../components/utils/Header.vue' | ||
| import Footer from '../components/utils/Footer.vue' | ||
| import Block from '../components/blocks/Block.vue' | ||
| import type { ListBlock, Summary } from '@services/../pl-serve-type-main/type/main' | ||
|
|
||
| const { t } = useI18n() | ||
| const isLoading = ref(true) | ||
| const blocks = ref<ListBlock[]>([]) | ||
| const { blockItemsPerRow, maxProjectsPerBlock } = useResponsive() | ||
|
|
||
| function createBlock(header: string, summaries: Summary[]): ListBlock { | ||
| return { | ||
| $type: 'Quantum.Models.Contents.ListBlock, Quantum Models', | ||
| Header: header, | ||
| Summaries: summaries, | ||
| DefaultLink: null, | ||
| DefaultText: null, | ||
| FetchAmount: 0, | ||
| FetchConfiguration: null, | ||
| FetchSource: '', | ||
| Locations: null, | ||
| Permission: null, | ||
| TargetLink: '', | ||
| Type: 0, | ||
| } | ||
| } | ||
|
|
||
| async function querySummaries(category: 'Experiment' | 'Discussion', special: 'Favorite' | 'Support' | null) { | ||
| const response = await getData('/Contents/QueryExperiments', { | ||
| Query: { | ||
| Category: category, | ||
| Languages: [], | ||
| Tags: [], | ||
| Take: 24, | ||
| Sort: 0, | ||
| Skip: 0, | ||
| Days: 0, | ||
| Special: special, | ||
| UserID: null, | ||
| ExcludeLanguages: null, | ||
| ExcludeTags: null, | ||
| ModelTags: null, | ||
| ModelID: null, | ||
| ParentID: null, | ||
| From: null, | ||
| ShowAnnouncement: false, | ||
| }, | ||
| }) | ||
|
|
||
| return response.Data?.$values ?? [] | ||
| } | ||
|
|
||
| onMounted(async () => { | ||
| if (!checkLogin(false)) { | ||
| showLoginModel() | ||
| isLoading.value = false | ||
| return | ||
| } | ||
|
|
||
| const [publishedExp, publishedDiscussion, favoriteExp, favoriteDiscussion, supportExp, supportDiscussion] = | ||
| await Promise.all([ | ||
| querySummaries('Experiment', null), | ||
| querySummaries('Discussion', null), | ||
| querySummaries('Experiment', 'Favorite'), | ||
| querySummaries('Discussion', 'Favorite'), | ||
| querySummaries('Experiment', 'Support'), | ||
| querySummaries('Discussion', 'Support'), | ||
| ]) | ||
|
Comment on lines
+89
to
+97
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The six requests are awaited with Useful? React with 👍 / 👎. |
||
|
|
||
| blocks.value = [ | ||
| createBlock(t('myPage.publishedExperiment'), publishedExp), | ||
| createBlock(t('myPage.publishedDiscussion'), publishedDiscussion), | ||
| createBlock(t('myPage.favoriteExperiment'), favoriteExp), | ||
| createBlock(t('myPage.favoriteDiscussion'), favoriteDiscussion), | ||
| createBlock(t('myPage.supportedExperiment'), supportExp), | ||
| createBlock(t('myPage.supportedDiscussion'), supportDiscussion), | ||
| ] | ||
|
|
||
| isLoading.value = false | ||
| }) | ||
| </script> | ||
|
|
||
| <style scoped> | ||
| .my-page__title { | ||
| font-size: 20px; | ||
| font-weight: 600; | ||
| } | ||
|
|
||
| .my-page__block { | ||
| height: 100%; | ||
| } | ||
| </style> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This page only loads data in
onMounted, but the route is markedkeepAlive, so when an unauthenticated user opens/my, the component returns early and stays cached with emptyblocks; after completing login and returning to/my,onMountedwill not run again and the page remains empty until a full reload. Please trigger the same load flow on activation or onuserLoginso cached instances recover.Useful? React with 👍 / 👎.