From 310d4fbb75f19f036becc063e3aa2691d8c35b77 Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Mon, 3 Mar 2025 18:03:32 +0800 Subject: [PATCH 1/7] chore: bump CI SecretFlow version up to 1.11.0b1 --- .circleci/config.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index cef9aba..4257e6f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -102,7 +102,7 @@ workflows: arch: amd64 matrix: parameters: - tag: ['1.10.0b0', '1.9.0b0', '1.8.0b0', '1.7.0b0'] + tag: ['1.11.0b1', '1.10.0b0', '1.9.0b0', '1.8.0b0'] # Publish for linux/arm64 - devcontainer-publish-arm64: filters: @@ -112,7 +112,7 @@ workflows: arch: arm64 matrix: parameters: - tag: ['1.10.0b0', '1.9.0b0', '1.8.0b0', '1.7.0b0'] + tag: ['1.11.0b1', '1.10.0b0', '1.9.0b0', '1.8.0b0'] # Manifest they two and push to registry - devcontainer-manifest: requires: @@ -124,4 +124,4 @@ workflows: - main matrix: parameters: - tag: ['1.10.0b0', '1.9.0b0', '1.8.0b0', '1.7.0b0'] + tag: ['1.11.0b1', '1.10.0b0', '1.9.0b0', '1.8.0b0'] From 4241bac3911b3a90b2bfeb6478c1118ef27c9314 Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Mon, 3 Mar 2025 18:04:04 +0800 Subject: [PATCH 2/7] chore: bump version to 0.0.51 --- packages/secretnote-scql/package.json | 2 +- packages/secretnote-sf/package.json | 2 +- pyprojects/secretnote/package.json | 2 +- pyprojects/secretnote/secretnote/__init__.py | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/secretnote-scql/package.json b/packages/secretnote-scql/package.json index e6acb21..7e7699c 100644 --- a/packages/secretnote-scql/package.json +++ b/packages/secretnote-scql/package.json @@ -1,6 +1,6 @@ { "name": "@alipay/secretnote-scql", - "version": "0.0.50", + "version": "0.0.51", "license": "Apache-2.0", "author": "vectorse@126.com", "repository": "https://github.com/secretflow/secretnote/tree/main/packages/secretnote", diff --git a/packages/secretnote-sf/package.json b/packages/secretnote-sf/package.json index a714510..d160f99 100644 --- a/packages/secretnote-sf/package.json +++ b/packages/secretnote-sf/package.json @@ -1,6 +1,6 @@ { "name": "@alipay/secretnote-sf", - "version": "0.0.50", + "version": "0.0.51", "license": "Apache-2.0", "author": "vectorse@126.com", "repository": "https://github.com/secretflow/secretnote/tree/main/packages/secretnote", diff --git a/pyprojects/secretnote/package.json b/pyprojects/secretnote/package.json index d1fbc59..6bb4b89 100644 --- a/pyprojects/secretnote/package.json +++ b/pyprojects/secretnote/package.json @@ -1,7 +1,7 @@ { "name": "secretnote", "private": true, - "version": "0.0.50", + "version": "0.0.51", "type": "module", "scripts": { "dev:sf": "cd .. && NODE_ENV=development python -m secretnote sf --config=./secretnote/secretnote/sf/.jupyter/config_dev.py --no-browser", diff --git a/pyprojects/secretnote/secretnote/__init__.py b/pyprojects/secretnote/secretnote/__init__.py index bf41adb..a3ebe30 100644 --- a/pyprojects/secretnote/secretnote/__init__.py +++ b/pyprojects/secretnote/secretnote/__init__.py @@ -1 +1 @@ -__version__ = "0.0.50" +__version__ = "0.0.51" From 3ad26ae58282dd643bd6a5cf9f98698630048ef6 Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Mon, 3 Mar 2025 19:23:29 +0800 Subject: [PATCH 3/7] refactor: hide toolbar when preview --- packages/secretnote-sf/package.json | 4 ++-- packages/secretnote-sf/src/{index.tsx => index.ts} | 0 packages/secretnote-sf/src/pages/sf-preview/index.less | 7 +++++++ packages/secretnote-sf/src/pages/sf-preview/index.tsx | 7 ++++--- 4 files changed, 13 insertions(+), 5 deletions(-) rename packages/secretnote-sf/src/{index.tsx => index.ts} (100%) create mode 100644 packages/secretnote-sf/src/pages/sf-preview/index.less diff --git a/packages/secretnote-sf/package.json b/packages/secretnote-sf/package.json index d160f99..ac0f380 100644 --- a/packages/secretnote-sf/package.json +++ b/packages/secretnote-sf/package.json @@ -14,8 +14,8 @@ "types": "dist/index.d.ts", "scripts": { "prepare": "pnpm run build:component", - "build:component": "tsup src/index.tsx --inject react-shim.js", - "dev": "tsup src/index.tsx --watch --inject react-shim.js", + "build:component": "tsup src/index.ts --inject react-shim.js", + "dev": "tsup src/index.ts --watch --inject react-shim.js", "lint:eslint": "eslint . --ext ts,tsx", "typecheck:tsc": "tsc -p tsconfig.json --noEmit", "pb": "pnpm publish --no-git-checks --filter @secretflow/secretnote-sf" diff --git a/packages/secretnote-sf/src/index.tsx b/packages/secretnote-sf/src/index.ts similarity index 100% rename from packages/secretnote-sf/src/index.tsx rename to packages/secretnote-sf/src/index.ts diff --git a/packages/secretnote-sf/src/pages/sf-preview/index.less b/packages/secretnote-sf/src/pages/sf-preview/index.less new file mode 100644 index 0000000..03380ea --- /dev/null +++ b/packages/secretnote-sf/src/pages/sf-preview/index.less @@ -0,0 +1,7 @@ +.mana-view-container { + > .libro-view { + > .libro-view-top { + display: none; + } + } +} diff --git a/packages/secretnote-sf/src/pages/sf-preview/index.tsx b/packages/secretnote-sf/src/pages/sf-preview/index.tsx index bf1532b..2883800 100644 --- a/packages/secretnote-sf/src/pages/sf-preview/index.tsx +++ b/packages/secretnote-sf/src/pages/sf-preview/index.tsx @@ -16,6 +16,7 @@ import { ToolbarModule } from '@/modules/toolbar'; import '@/lang'; import { useRunOnce } from '@/utils/hook'; import '../../override.less'; +import './index.less'; export interface ISecretNotePreviewProps { fileURL?: string; // file URL of the notebook to preview @@ -23,9 +24,9 @@ export interface ISecretNotePreviewProps { } const App = (props: ISecretNotePreviewProps): JSX.Element => { - useRunOnce(() => - localStorage.setItem(SecretNoteConfigLocalStorageKey, JSON.stringify(props)), - ); + useRunOnce(() => { + localStorage.setItem(SecretNoteConfigLocalStorageKey, JSON.stringify(props)); + }); return ( Date: Mon, 3 Mar 2025 19:56:52 +0800 Subject: [PATCH 4/7] refactor: don't autoFocus tiptap on notebook open --- .../src/components/markdown-editor/index.tsx | 1 - packages/secretnote-sf/src/pages/sf-preview/index.less | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/secretnote-sf/src/components/markdown-editor/index.tsx b/packages/secretnote-sf/src/components/markdown-editor/index.tsx index b0554e2..bd8c25f 100644 --- a/packages/secretnote-sf/src/components/markdown-editor/index.tsx +++ b/packages/secretnote-sf/src/components/markdown-editor/index.tsx @@ -58,7 +58,6 @@ export function Editor({ onUpdate(e.editor); debouncedUpdates(e); }, - autofocus: 'end', }); // Hydrate the editor with the content from localStorage. diff --git a/packages/secretnote-sf/src/pages/sf-preview/index.less b/packages/secretnote-sf/src/pages/sf-preview/index.less index 03380ea..28efadf 100644 --- a/packages/secretnote-sf/src/pages/sf-preview/index.less +++ b/packages/secretnote-sf/src/pages/sf-preview/index.less @@ -1,7 +1,9 @@ -.mana-view-container { - > .libro-view { - > .libro-view-top { - display: none; +.secretnote-sf-preview-container { + .mana-view-container { + > .libro-view { + > .libro-view-top { + display: none; + } } } } From bd3312da44b9f61537c75fa0d7b5a55ce95322ac Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Tue, 4 Mar 2025 12:08:30 +0800 Subject: [PATCH 5/7] refactor: optimize ribbon style --- .../src/components/ribbon/index.less | 6 +++- .../src/components/ribbon/index.tsx | 35 +++++++++++-------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/packages/secretnote-sf/src/components/ribbon/index.less b/packages/secretnote-sf/src/components/ribbon/index.less index dbb7a8b..86f0024 100644 --- a/packages/secretnote-sf/src/components/ribbon/index.less +++ b/packages/secretnote-sf/src/components/ribbon/index.less @@ -3,8 +3,12 @@ } .secretnote-ribbon-popover { - .title { + .mb-2 { margin-bottom: 8px; + } + + .title { + margin-bottom: 6px; color: var(--mana-secretnote-text-color); } diff --git a/packages/secretnote-sf/src/components/ribbon/index.tsx b/packages/secretnote-sf/src/components/ribbon/index.tsx index 6268a95..4536263 100644 --- a/packages/secretnote-sf/src/components/ribbon/index.tsx +++ b/packages/secretnote-sf/src/components/ribbon/index.tsx @@ -1,3 +1,5 @@ +// This is the ribbon on the top-right corner of each code cell used for selecting parties. + import { l10n } from '@difizen/mana-l10n'; import { Badge, Popover, Space, Tag } from 'antd'; import React from 'react'; @@ -5,8 +7,8 @@ import './index.less'; interface RibbonProps { children: React.ReactNode; - items: { label: string; key: string }[]; - value: string[]; + items: { label: string; key: string }[]; // selectable parties that are already added nodes + value: string[]; // selected parties that is saved in the metadata of the cell execution onChange?: (value: string[]) => void; readonly?: boolean; } @@ -44,20 +46,23 @@ function Ribbon(props: RibbonProps) { overlayClassName="secretnote-ribbon-popover" content={ <> -
{l10n.t('请选择要执行该代码的节点列表')}:
+
{l10n.t('请选择要执行该代码的节点列表')}
- {items.map((item) => ( - handleChange(item.key, checked)} - > - {item.label} - - ))} + {items.length + ? items.map((item) => ( + handleChange(item.key, checked)} + > + {item.label} + + )) + : l10n.t('还未拉起任何节点')} } From 5d2e2e824ad290dcf51b6a71118f6b1132f3c0b4 Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Tue, 4 Mar 2025 14:00:45 +0800 Subject: [PATCH 6/7] feat: hint required parties to the user when open notebook --- packages/secretnote-scql/src/utils/error.ts | 2 +- .../src/modules/editor/cell/view.tsx | 31 ++++++----- .../editor/contents/contents-contrib.ts | 55 +++++++++++++++---- .../secretnote-sf/src/utils/array-object.ts | 11 ++++ packages/secretnote-sf/src/utils/error.ts | 4 +- 5 files changed, 75 insertions(+), 28 deletions(-) diff --git a/packages/secretnote-scql/src/utils/error.ts b/packages/secretnote-scql/src/utils/error.ts index 50f0271..6fdc544 100644 --- a/packages/secretnote-scql/src/utils/error.ts +++ b/packages/secretnote-scql/src/utils/error.ts @@ -14,6 +14,7 @@ export function genericErrorHandler( reThrow?: boolean; } = {}, ) { + // eslint-disable-next-line no-console console.error(e); const { passthrough } = options; let { silent, reThrow } = options; @@ -23,7 +24,6 @@ export function genericErrorHandler( if (!silent) { message.error(e?.message || e.toString()); } - // eslint-disable-next-line no-console if (reThrow) { throw e; } diff --git a/packages/secretnote-sf/src/modules/editor/cell/view.tsx b/packages/secretnote-sf/src/modules/editor/cell/view.tsx index 870b354..5f81a5c 100644 --- a/packages/secretnote-sf/src/modules/editor/cell/view.tsx +++ b/packages/secretnote-sf/src/modules/editor/cell/view.tsx @@ -37,20 +37,20 @@ import { compareDateString, isReadonly } from '@/utils'; const SecretNoteCodeCellComponent = forwardRef((props, ref) => { const instance = useInject(ViewInstance); - const { partyList, parties } = instance; + const { allParties, cellParties } = instance; const { readonly } = instance; return (
({ + items={(readonly ? cellParties : allParties).map((name) => ({ label: name, key: name, }))} - value={parties} + value={cellParties} onChange={(val) => { !readonly && instance.onPartiesChange(val); }} @@ -72,10 +72,10 @@ export class SecretNoteCodeCellView extends JupyterCodeCellView { view = SecretNoteCodeCellComponent; - @prop() parties: string[] = []; + @prop() cellParties: string[] = []; @prop() readonly = false; - get partyList() { + get allParties() { return this.serverManager.servers .filter((s) => s.status === ServerStatus.Succeeded) .map((server) => server.name); @@ -94,7 +94,7 @@ export class SecretNoteCodeCellView extends JupyterCodeCellView { this.serverManager = serverManager; this.kernelManager = kernelManager; this.readonly = isReadonly(configService); - this.parties = this.getInitialParties(); + this.cellParties = this.getInitialParties(); } /** @@ -114,7 +114,7 @@ export class SecretNoteCodeCellView extends JupyterCodeCellView { return ( server && server.status === ServerStatus.Succeeded && - this.parties.includes(server.name) + this.cellParties.includes(server.name) ); }); } @@ -258,7 +258,7 @@ export class SecretNoteCodeCellView extends JupyterCodeCellView { * Handle the change of parties user selected on the right-top corner of the cell. */ onPartiesChange(parties: string[]) { - this.parties = parties; + this.cellParties = parties; this.savePartiesToMeta(parties); lastParties = parties; } @@ -275,23 +275,24 @@ export class SecretNoteCodeCellView extends JupyterCodeCellView { if (execution && execution.parties) { try { const parties: string[] = JSON.parse(execution.parties as string); - return this.readonly - ? parties - : // filter out parties that are not in the server list - parties.filter((p) => this.partyList.includes(p)); + if (this.readonly) { + return parties; + } + // filter out parties that are not in the server list + return parties.filter((p) => this.allParties.includes(p)); } catch (e) { return []; } } else if (lastParties.length > 0) { return lastParties; // load parties from previous cell settings } - return this.partyList; + return this.allParties; } /** * Save the parties user selected to the cell model metadata. */ - savePartiesToMeta(parties = this.parties) { + savePartiesToMeta(parties = this.cellParties) { const execution = this.model.metadata.execution as ExecutionMeta; if (execution) { execution.parties = JSON.stringify(parties); diff --git a/packages/secretnote-sf/src/modules/editor/contents/contents-contrib.ts b/packages/secretnote-sf/src/modules/editor/contents/contents-contrib.ts index b14189f..f3e1af3 100644 --- a/packages/secretnote-sf/src/modules/editor/contents/contents-contrib.ts +++ b/packages/secretnote-sf/src/modules/editor/contents/contents-contrib.ts @@ -1,42 +1,77 @@ -import type { NotebookModel, NotebookOption } from '@difizen/libro-jupyter'; -import { ContentContribution } from '@difizen/libro-jupyter'; +import type { ICell, NotebookModel, NotebookOption } from '@difizen/libro-jupyter'; +import { ContentContribution, isCode } from '@difizen/libro-jupyter'; import { URI, inject, singleton } from '@difizen/mana-app'; +import { l10n } from '@difizen/mana-l10n'; +import { message } from 'antd'; +import { uniq } from 'lodash-es'; +import { SecretNoteConfigService } from '@/modules/config'; import type { SecretNoteModel } from '@/modules/editor'; import { NotebookFileService } from '@/modules/notebook'; +import { genericErrorHandler, isReadonly, jsonParseSafe } from '@/utils'; @singleton({ contrib: ContentContribution }) export class SecretNoteContentContribution implements ContentContribution { protected readonly notebookFileService: NotebookFileService; + protected readonly configService: SecretNoteConfigService; - constructor(@inject(NotebookFileService) notebookFileService: NotebookFileService) { + constructor( + @inject(NotebookFileService) notebookFileService: NotebookFileService, + @inject(SecretNoteConfigService) configService: SecretNoteConfigService, + ) { this.notebookFileService = notebookFileService; + this.configService = configService; } canHandle = () => { return 3; }; - async loadContent(options: NotebookOption, model: NotebookModel) { - const secretNoteModel = model as SecretNoteModel; + async loadContent(options: NotebookOption, _model: NotebookModel) { + const model = _model as SecretNoteModel; const fileUri = new URI(options.resource); const filePath = fileUri.path.toString(); const currentFileContents = await this.notebookFileService.getFile(filePath); if (currentFileContents) { currentFileContents.content.nbformat_minor = 5; - secretNoteModel.currentFileContents = currentFileContents; + model.currentFileContents = currentFileContents; // use file path as id, will be passed to editor and lsp // @see https://github.com/difizen/libro/commit/b91cd7588ba4adcb3ca83f241fe42471b30cdc26#diff-32d01fca78d40feed75dcc29437fae22f74ebe33ec16ee11fde7c6c220bedbdbR23 - secretNoteModel.id = secretNoteModel.filePath = currentFileContents.path; + model.id = model.filePath = currentFileContents.path; /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ // @ts-ignore - if (!secretNoteModel.quickEditMode && !secretNoteModel.readOnly) { - secretNoteModel.startKernelConnection(); + if (!model.quickEditMode && !model.readOnly) { + model.startKernelConnection(); } - return secretNoteModel.currentFileContents.content; + const { content } = model.currentFileContents; + // collect all parties in execution metadata and hint the user if possible + try { + if (!isReadonly(this.configService)) { + const requiredParties = uniq( + content?.cells + .map((v: ICell) => + // @ts-ignore + isCode(v) ? jsonParseSafe(v?.metadata?.execution?.parties, []) : [], + ) + .flat() as string[], + ); + requiredParties.length && + message.info( + l10n.t( + `当前 Notebook 需要参与方 {0} 执行,添加完成后请刷新页面`, + requiredParties.join(', '), + ), + 5, + ); + } + } catch (e) { + genericErrorHandler(e, { silent: true }); + } + + return content; } } } diff --git a/packages/secretnote-sf/src/utils/array-object.ts b/packages/secretnote-sf/src/utils/array-object.ts index 024ba80..18527ad 100644 --- a/packages/secretnote-sf/src/utils/array-object.ts +++ b/packages/secretnote-sf/src/utils/array-object.ts @@ -40,3 +40,14 @@ export function pickExcept(obj: T, keys: K[ Object.keys(obj).filter((k) => !keys.includes(k as K)), ) as Omit; } + +/** + * JSON parse with fallback. + */ +export function jsonParseSafe(json: string, fallback: any = {}) { + try { + return JSON.parse(json); + } catch (e) { + return fallback; + } +} diff --git a/packages/secretnote-sf/src/utils/error.ts b/packages/secretnote-sf/src/utils/error.ts index e05ee23..67673b3 100644 --- a/packages/secretnote-sf/src/utils/error.ts +++ b/packages/secretnote-sf/src/utils/error.ts @@ -14,11 +14,11 @@ export function genericErrorHandler( reThrow?: boolean; } = {}, ) { + // eslint-disable-next-line no-console + console.error(e); if (!options?.silent) { message.error(getErrorString(e)); - console.error(e); } - // eslint-disable-next-line no-console if (options?.reThrow) { throw e; } From 8021ec0b0d59baf5f4426a35be8b9efed879d2e9 Mon Sep 17 00:00:00 2001 From: z0gSh1u Date: Tue, 4 Mar 2025 14:19:18 +0800 Subject: [PATCH 7/7] fix: pass ci --- .eslintrc.cjs | 1 + .../src/modules/editor/contents/contents-contrib.ts | 1 - packages/secretnote-sf/src/pages/sf-preview/index.tsx | 2 +- packages/secretnote-sf/src/pages/sf-workspace/index.tsx | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 0adf756..1c7392a 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -17,6 +17,7 @@ module.exports = { rules: { // let's bypass them 'promise/always-return': 'off', + '@typescript-eslint/ban-ts-comment': 'warn', // common pitfalls eqeqeq: 'error', diff --git a/packages/secretnote-sf/src/modules/editor/contents/contents-contrib.ts b/packages/secretnote-sf/src/modules/editor/contents/contents-contrib.ts index f3e1af3..30adacc 100644 --- a/packages/secretnote-sf/src/modules/editor/contents/contents-contrib.ts +++ b/packages/secretnote-sf/src/modules/editor/contents/contents-contrib.ts @@ -40,7 +40,6 @@ export class SecretNoteContentContribution implements ContentContribution { // @see https://github.com/difizen/libro/commit/b91cd7588ba4adcb3ca83f241fe42471b30cdc26#diff-32d01fca78d40feed75dcc29437fae22f74ebe33ec16ee11fde7c6c220bedbdbR23 model.id = model.filePath = currentFileContents.path; - /* eslint-disable-next-line @typescript-eslint/ban-ts-comment */ // @ts-ignore if (!model.quickEditMode && !model.readOnly) { model.startKernelConnection(); diff --git a/packages/secretnote-sf/src/pages/sf-preview/index.tsx b/packages/secretnote-sf/src/pages/sf-preview/index.tsx index 2883800..49d2a2c 100644 --- a/packages/secretnote-sf/src/pages/sf-preview/index.tsx +++ b/packages/secretnote-sf/src/pages/sf-preview/index.tsx @@ -12,9 +12,9 @@ import { } from '@/modules/preview'; import { ThemeModule } from '@/modules/theme'; import { ToolbarModule } from '@/modules/toolbar'; +import { useRunOnce } from '@/utils/hook'; import '@/lang'; -import { useRunOnce } from '@/utils/hook'; import '../../override.less'; import './index.less'; diff --git a/packages/secretnote-sf/src/pages/sf-workspace/index.tsx b/packages/secretnote-sf/src/pages/sf-workspace/index.tsx index bd10110..792b79e 100644 --- a/packages/secretnote-sf/src/pages/sf-workspace/index.tsx +++ b/packages/secretnote-sf/src/pages/sf-workspace/index.tsx @@ -15,10 +15,10 @@ import { ThemeModule } from '@/modules/theme'; import { ToolbarModule } from '@/modules/toolbar'; import { SnippetModule } from '@/modules/toolbar/snippet'; import { WelcomeModule } from '@/modules/welcome'; +import { useRunOnce } from '@/utils/hook'; // import { ComponentCellModule } from '@/modules/component-cell' import '@/lang'; -import { useRunOnce } from '@/utils/hook'; import '../../override.less'; export interface ISecretNoteWorkspaceProps {