diff --git a/client/packages/openblocks/src/i18n/locales/enObj.tsx b/client/packages/openblocks/src/i18n/locales/enObj.tsx index f47b43c3..72fe80cc 100644 --- a/client/packages/openblocks/src/i18n/locales/enObj.tsx +++ b/client/packages/openblocks/src/i18n/locales/enObj.tsx @@ -112,7 +112,7 @@ export const enObj: I18nObjects = { ], }, editorTutorials: { - mockDataUrl: "https://63621db87521369cd06514c2.mockapi.io/api/openblocks/users", + mockScript: "return new Promise(r => {\n setTimeout(() => r([\n { name: \"Ron Cormier\", avatar: \"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1199.jpg\", city: \"Port Isadore\", email: \"Letitia.Luettgen39@yahoo.com\", createAt: \"2022-11-01T10:29:17.119Z\", id: 1 },\n { name: \"Glen Quitzon\", avatar: \"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/729.jpg\", city: \"Sporerside\", email: \"Candice_Schimmel@yahoo.com\", createAt: \"2022-11-01T16:42:37.766Z\", id: 2 },\n { name: \"Tamara Kreiger III\", avatar: \"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/992.jpg\", city: \"West Maryam\", email: \"Margie_Lynch@gmail.com\", createAt: \"2022-11-01T19:58:12.285Z\", id: 3 },\n { name: \"Edgar Stokes\", avatar: \"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/25.jpg\", city: \"North Richland Hills\", email: \"Jan77@gmail.com\", createAt: \"2022-11-01T23:39:32.720Z\", id: 4 },\n ]), 500)\n})", data: (code) => ( <> The component and query data are listed here, which can be referenced through diff --git a/client/packages/openblocks/src/i18n/locales/ptObj.tsx b/client/packages/openblocks/src/i18n/locales/ptObj.tsx index bc6e8ac5..c9dc9dbb 100644 --- a/client/packages/openblocks/src/i18n/locales/ptObj.tsx +++ b/client/packages/openblocks/src/i18n/locales/ptObj.tsx @@ -1,4 +1,24 @@ +/* eslint-disable only-ascii/only-ascii */ import { enObj } from "./enObj"; import { I18nObjects } from "./types"; -export const ptObj: I18nObjects = enObj; +export const ptObj: I18nObjects = { + ...enObj, + editorTutorials: { + mockScript: "return new Promise(r => {\n setTimeout(() => r([\n { name: \"Ron Cormier\", avatar: \"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/1199.jpg\", city: \"Port Isadore\", email: \"Letitia.Luettgen39@yahoo.com\", createAt: \"2022-11-01T10:29:17.119Z\", id: 1 },\n { name: \"Glen Quitzon\", avatar: \"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/729.jpg\", city: \"Sporerside\", email: \"Candice_Schimmel@yahoo.com\", createAt: \"2022-11-01T16:42:37.766Z\", id: 2 },\n { name: \"Tamara Kreiger III\", avatar: \"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/992.jpg\", city: \"West Maryam\", email: \"Margie_Lynch@gmail.com\", createAt: \"2022-11-01T19:58:12.285Z\", id: 3 },\n { name: \"Edgar Stokes\", avatar: \"https://cloudflare-ipfs.com/ipfs/Qmd3W5DuhgHirLHGVixi6V76LhCkZUz6pnFt5AJBiyvHye/avatar/25.jpg\", city: \"North Richland Hills\", email: \"Jan77@gmail.com\", createAt: \"2022-11-01T23:39:32.720Z\", id: 4 },\n ]), 500)\n})", + data: (code) => ( + <> + O componente e os dados da consulta estão listados aqui, os quais podem ser referenciados por + {code("{{ }}")}. Por exemplo: {code("{{table1.selectedRow}}")}. + + ), + compProperties: (code) => ( + <> + Quando um componente é selecionado, as propriedades dele são mostradas no painel direito + {code("{{query1.data}}")}. Para referenciar os dados já consultados, você pode usar na caixa de texto + {code("{{ }}")} + o seguinte JavaScript. + + ), + }, +}; diff --git a/client/packages/openblocks/src/i18n/locales/types.tsx b/client/packages/openblocks/src/i18n/locales/types.tsx index 4c797001..0e654697 100644 --- a/client/packages/openblocks/src/i18n/locales/types.tsx +++ b/client/packages/openblocks/src/i18n/locales/types.tsx @@ -12,7 +12,7 @@ export type I18nObjects = { }; editorTutorials: { sampleDatasourceName?: string; - mockDataUrl?: string; + mockScript?: string; data: ( code: (text: string) => React.ReactNode, link: (text: string, url: string) => React.ReactNode diff --git a/client/packages/openblocks/src/pages/common/help.tsx b/client/packages/openblocks/src/pages/common/help.tsx index 0072fbfb..d55d1cb9 100644 --- a/client/packages/openblocks/src/pages/common/help.tsx +++ b/client/packages/openblocks/src/pages/common/help.tsx @@ -26,6 +26,8 @@ import { QuestionIcon, UpgradeIcon } from "openblocks-design"; import { trans } from "i18n"; import { localEnv } from "util/envUtils"; +import { v4 } from "uuid"; + const StyledMenu = styled(DropdownMenu)<{ $edit: boolean | string }>` ${(props) => props.$edit && @@ -238,7 +240,7 @@ export function HelpDropdown(props: HelpDropdownProps) { case "editorTutorial": dispatch( createApplication({ - applicationName: trans("help.appName"), + applicationName: trans("help.appName") + " - " + v4().split("-")[0], applicationType: AppTypeEnum.Application, orgId: user.currentOrgId, onSuccess: (app) => { diff --git a/client/packages/openblocks/src/pages/tutorials/editorTutorials.tsx b/client/packages/openblocks/src/pages/tutorials/editorTutorials.tsx index bee5c3ed..463445ce 100644 --- a/client/packages/openblocks/src/pages/tutorials/editorTutorials.tsx +++ b/client/packages/openblocks/src/pages/tutorials/editorTutorials.tsx @@ -10,8 +10,7 @@ import { } from "openblocks-core"; import { addMapChildAction } from "comps/generators/sameTypeMap"; import { genQueryId, genRandomKey } from "comps/utils/idGenerator"; -import { useDispatch, useSelector } from "react-redux"; -import { AppState } from "redux/reducers"; +import { useDispatch } from "react-redux"; import { defaultJoyrideFloaterProps, defaultJoyrideStyles, @@ -30,9 +29,7 @@ import { uiCompRegistry, UICompType } from "comps/uiCompRegistry"; import { BottomResTypeEnum } from "types/bottomRes"; import { trans } from "i18n"; import { i18nObjs } from "../../i18n/index"; -import { DatasourceInfo, HttpConfig } from "api/datasourceApi"; import { enObj } from "i18n/locales"; -import { QUICK_REST_API_ID } from "constants/datasourceConstants"; const tourSteps: Step[] = [ { @@ -148,7 +145,7 @@ function addTable(editorState: EditorState) { ); } -function addQuery(editorState: EditorState, datasourceInfos: DatasourceInfo[]) { +function addQuery(editorState: EditorState) { const queryName = "query1"; if ( editorState @@ -161,36 +158,18 @@ function addQuery(editorState: EditorState, datasourceInfos: DatasourceInfo[]) { } const queriesComp = editorState.getQueriesComp(); const id = genQueryId(); - let dataSourceComp = datasourceInfos.find( - (info) => info.datasource.name === i18nObjs.editorTutorials.sampleDatasourceName + queriesComp.dispatch( + queriesComp.pushAction({ + id, + name: queryName, + compType: "js", + comp: { + script: i18nObjs.editorTutorials.mockScript || enObj.editorTutorials.mockScript + }, + datasourceId: "", + triggerType: "manual", + }) ); - if (dataSourceComp) { - queriesComp.dispatch( - queriesComp.pushAction({ - id: id, - name: queryName, - compType: "mysql", - comp: { sql: "SELECT * FROM users;", commandType: "INSERT" }, - datasourceId: dataSourceComp?.datasource.id || "", - triggerType: "manual", - }) - ); - } else { - // there's no sample data source, fall back to api source - queriesComp.dispatch( - queriesComp.pushAction({ - id: id, - name: queryName, - compType: "restApi", - comp: { - path: i18nObjs.editorTutorials.mockDataUrl || enObj.editorTutorials.mockDataUrl, - bodyType: "application/json", - }, - datasourceId: QUICK_REST_API_ID, - triggerType: "manual", - }) - ); - } editorState.setSelectedBottomRes(queryName, BottomResTypeEnum.Query); } @@ -200,13 +179,11 @@ export default function EditorTutorials() { const editorState = useContext(EditorContext); const dispatch = useDispatch(); const history = useHistory(); - const datasourceInfos = useSelector((state: AppState) => state.entities.datasource.data); useEffect(() => { setRun(true); }, []); const querySize = editorState.getQueriesComp().getView().length; - const uiCompSize = editorState.uiCompInfoList().length; useEffect(() => { const query = editorState .getQueriesComp() @@ -258,10 +235,10 @@ export default function EditorTutorials() { } else if (index === 1 && action === ACTIONS.NEXT) { // re-try to add table in case of the deletion in the prev step addTable(editorState); - addQuery(editorState, datasourceInfos); + addQuery(editorState); // select table in advance editorState.setSelectedCompNames(new Set(["table1"])); - setStepIndex(nextIndex); + setTimeout(() => setStepIndex(nextIndex), 0); } else if (index === 2 && action === ACTIONS.NEXT) { // change data openTableData(); diff --git a/proxy/src/api/pocketbase/types.ts b/proxy/src/api/pocketbase/types.ts index bee60c25..d0c3bfa4 100644 --- a/proxy/src/api/pocketbase/types.ts +++ b/proxy/src/api/pocketbase/types.ts @@ -55,6 +55,7 @@ export interface PBUser extends BaseModel { name: string; avatar?: string; avatar_url?: string; + show_tutorial?: boolean; } type ConfigExpanded = { diff --git a/proxy/src/mocks/users/index.ts b/proxy/src/mocks/users/index.ts index 272620ef..76adf1b1 100644 --- a/proxy/src/mocks/users/index.ts +++ b/proxy/src/mocks/users/index.ts @@ -1,5 +1,6 @@ import currentUser from "./currentUser"; +import markStatus from "./mark-status"; import me from "./me"; import password from "./password"; -export default [...currentUser, ...me, ...password]; +export default [...currentUser, ...markStatus, ...me, ...password]; diff --git a/proxy/src/mocks/users/mark-status.ts b/proxy/src/mocks/users/mark-status.ts new file mode 100644 index 00000000..1609ec18 --- /dev/null +++ b/proxy/src/mocks/users/mark-status.ts @@ -0,0 +1,31 @@ +import { auth, users } from "@/api"; +import { mocker } from "@/mocker"; +import { + adminRoute, + createDefaultErrorResponse, + createDefaultResponse, +} from "@/utils"; + +export default [ + mocker.put( + "/api/users/mark-status", + adminRoute(async (req) => { + const { type, value } = req.config.data; + if (type === "newUserGuidance") { + const authResponse = await auth.getCurrentUser(); + if (!authResponse.data) { + return createDefaultErrorResponse([{ status: 401 }]); + } + const updateUserResponse = await users.update({ + id: authResponse.data.id, + show_tutorial: !value, + }); + if (updateUserResponse.status === 200) { + return createDefaultResponse(); + } + return createDefaultErrorResponse([updateUserResponse]); + } + return createDefaultResponse(); + }), + ), +]; diff --git a/proxy/src/mocks/users/me.ts b/proxy/src/mocks/users/me.ts index 782033d5..16b35af2 100644 --- a/proxy/src/mocks/users/me.ts +++ b/proxy/src/mocks/users/me.ts @@ -91,7 +91,7 @@ const createResponseData = async (user: FullUser, systemSettings: Settings) => { hasSetNickname: true, hasShownNewUserGuidance: false, userStatus: { - newUserGuidance: true, + newUserGuidance: !user.show_tutorial, }, createdTimeMs: new Date(user.created).getTime(), ip: "", diff --git a/proxy/src/types.ts b/proxy/src/types.ts index f0eb9ebd..8a839231 100644 --- a/proxy/src/types.ts +++ b/proxy/src/types.ts @@ -34,6 +34,7 @@ export interface User extends BaseModel { user_id: string; name: string; avatar?: string; + show_tutorial?: boolean; } export interface FullUser extends User { diff --git a/server/pb_hooks/pbl_hooks.pb.js b/server/pb_hooks/pbl_hooks.pb.js index c762c080..b1e2d48e 100644 --- a/server/pb_hooks/pbl_hooks.pb.js +++ b/server/pb_hooks/pbl_hooks.pb.js @@ -8,6 +8,7 @@ onAdminAfterCreateRequest((e) => { form.loadData({ name: "NONAME", user_id: e.admin.id, + show_tutorial: true, }); form.submit(); @@ -27,6 +28,7 @@ onRecordAfterCreateRequest((e) => { form.loadData({ name: "NONAME", user_id: e.record.get("id"), + show_tutorial: false, }); form.submit(); }, "users"); diff --git a/server/pb_hooks/pbl_utils.js b/server/pb_hooks/pbl_utils.js index 600453e3..327accb2 100644 --- a/server/pb_hooks/pbl_utils.js +++ b/server/pb_hooks/pbl_utils.js @@ -551,6 +551,16 @@ module.exports = { onlyDomains: null, }, }, + { + system: false, + id: "alphesl4", + name: "show_tutorial", + type: "bool", + required: false, + presentable: false, + unique: false, + options: {}, + }, ], indexes: [ "CREATE UNIQUE INDEX `idx_PiBIa6f` ON `pbl_users` (`user_id`)", @@ -699,7 +709,7 @@ module.exports = { id: "emmg3c0n", name: "app_dsl", type: "json", - required: true, + required: false, presentable: false, unique: false, options: {}, @@ -709,7 +719,7 @@ module.exports = { id: "xf4jqmlk", name: "edit_dsl", type: "json", - required: true, + required: false, presentable: false, unique: false, options: {},