├── README.md ├── studio ├── README.md ├── .env ├── public │ ├── locales │ │ ├── de │ │ │ └── translation.json │ │ └── zh │ │ │ └── translation.json │ ├── logo.png │ ├── favicon.png │ ├── logo192.png │ ├── logo512.png │ ├── img │ │ ├── bird.png │ │ ├── bird2.png │ │ ├── blank.png │ │ ├── install.png │ │ ├── install1.png │ │ ├── install2.png │ │ ├── install3.png │ │ ├── login1.png │ │ ├── login2.png │ │ ├── mobile.png │ │ ├── security.png │ │ ├── website.png │ │ ├── login1-big.png │ │ ├── background1.jpg │ │ ├── background2.jpg │ │ ├── design-team.png │ │ └── install1-big.png │ ├── robots.txt │ └── manifest.json ├── src │ ├── plugin-sdk │ │ ├── icon │ │ │ ├── index.ts │ │ │ └── model.ts │ │ ├── locales │ │ │ ├── index.ts │ │ │ ├── commonLocales.ts │ │ │ └── styleLocales.ts │ │ ├── hooks │ │ │ └── index.ts │ │ ├── contexts │ │ │ ├── index.ts │ │ │ └── login.ts │ │ ├── model │ │ │ ├── index.ts │ │ │ ├── IDataSourceableProps.ts │ │ │ └── IMenuNode.ts │ │ └── index.ts │ ├── react-app-env.d.ts │ ├── designer │ │ ├── AppBpmn │ │ │ ├── IModeler.ts │ │ │ ├── plugins │ │ │ │ ├── palette │ │ │ │ │ ├── index.ts │ │ │ │ │ └── CustomPaletteProvider.ts │ │ │ │ ├── context-pad │ │ │ │ │ ├── index.ts │ │ │ │ │ └── CustomContextPadProvider.ts │ │ │ │ └── replace │ │ │ │ │ └── index.ts │ │ │ ├── PropertyPanel │ │ │ │ ├── items │ │ │ │ │ ├── IdItem.tsx │ │ │ │ │ ├── NameItem.tsx │ │ │ │ │ ├── AssgnmentItem.tsx │ │ │ │ │ └── DocumentItem.tsx │ │ │ │ ├── elements │ │ │ │ │ ├── IElement.ts │ │ │ │ │ ├── useAssociation.tsx │ │ │ │ │ ├── useLane.tsx │ │ │ │ │ ├── useElementName.ts │ │ │ │ │ ├── useParticipant.tsx │ │ │ │ │ └── useCollaboration.tsx │ │ │ │ └── style.less │ │ │ ├── hooks │ │ │ │ ├── useProcesses.ts │ │ │ │ ├── useCategories.ts │ │ │ │ ├── useGetProcess.ts │ │ │ │ ├── useGetCategoryProcesses.ts │ │ │ │ ├── useDeleteProcess.ts │ │ │ │ ├── useCustomTranslate.ts │ │ │ │ ├── useDeleteCategory.ts │ │ │ │ ├── useProcessesWithoutCategory.ts │ │ │ │ ├── useQueryOneProcess.ts │ │ │ │ ├── useDeployProcess.ts │ │ │ │ ├── useUpsertProcess.ts │ │ │ │ └── useQueryCagegories.ts │ │ │ ├── ProcessList │ │ │ │ └── index.less │ │ │ └── recoil │ │ │ │ └── atoms.ts │ │ ├── AppUml │ │ │ ├── EntityTree │ │ │ │ ├── PackageLabel │ │ │ │ │ └── style.less │ │ │ │ ├── svgs.tsx │ │ │ │ ├── CodeLabel │ │ │ │ │ └── index.tsx │ │ │ │ └── OrchestrationLabel │ │ │ │ │ └── index.tsx │ │ │ ├── GraphCanvas │ │ │ │ ├── nodeInitSize.ts │ │ │ │ ├── ClassView │ │ │ │ │ ├── useMountRef.ts │ │ │ │ │ └── ClassNodeData.ts │ │ │ │ ├── getGraphSize.ts │ │ │ │ ├── useExplorerScrollbarHide.ts │ │ │ │ ├── constLabelPosition.ts │ │ │ │ ├── useDnd.ts │ │ │ │ ├── useTriggerSelectedEvent.ts │ │ │ │ ├── useTriggerPressedLineTypeEvent.ts │ │ │ │ ├── canStartLink.ts │ │ │ │ └── events │ │ │ │ │ └── index.ts │ │ │ ├── meta │ │ │ │ ├── CodeMeta.ts │ │ │ │ ├── OrchestrationMeta.ts │ │ │ │ ├── X6NodeMeta.ts │ │ │ │ ├── PackageMeta.ts │ │ │ │ ├── index.ts │ │ │ │ ├── DiagramMeta.ts │ │ │ │ ├── X6EdgeMeta.ts │ │ │ │ ├── Type.ts │ │ │ │ └── Meta.ts │ │ │ ├── consts.ts │ │ │ ├── recoil │ │ │ │ └── LineAction.ts │ │ │ ├── style.less │ │ │ ├── hooks │ │ │ │ ├── useClass.ts │ │ │ │ ├── useParseRelationUuid.ts │ │ │ │ ├── helper │ │ │ │ │ └── FileHandlers.ts │ │ │ │ ├── useRelation.ts │ │ │ │ ├── useSelectedCode.ts │ │ │ │ ├── useIsCode.ts │ │ │ │ ├── useIsDiagram.ts │ │ │ │ ├── useSelectedRelation.ts │ │ │ │ ├── useGetClass.ts │ │ │ │ ├── useGetCodeByName.ts │ │ │ │ ├── useGetPackage.ts │ │ │ │ ├── useGetClassByName.ts │ │ │ │ ├── useSelectedOrcherstration.ts │ │ │ │ ├── useClassPackage.ts │ │ │ │ ├── useDiagramNodes.ts │ │ │ │ ├── useGetPackageByName.ts │ │ │ │ ├── useGetRelation.ts │ │ │ │ ├── useEnums.ts │ │ │ │ ├── useEntities.ts │ │ │ │ ├── useGetDiagramByName.ts │ │ │ │ ├── useIsOrchestration.ts │ │ │ │ ├── useSelectedDiagramPackageUuid.ts │ │ │ │ ├── useValueObjects.ts │ │ │ │ ├── useGetEdge.ts │ │ │ │ ├── useGetNode.ts │ │ │ │ ├── useGetOrchestrationByName.ts │ │ │ │ ├── useGetDiagramNode.ts │ │ │ │ ├── useChangePackage.ts │ │ │ │ ├── useFirstChildrenUuids.ts │ │ │ │ ├── useGetSourceRelations.ts │ │ │ │ ├── useMethod.ts │ │ │ │ ├── useGetTargetRelations.ts │ │ │ │ ├── useAttribute.ts │ │ │ │ ├── useCheckOrchestrationName.ts │ │ │ │ ├── useDeletePackage.ts │ │ │ │ ├── usePublished.ts │ │ │ │ ├── useCreateClassMethod.ts │ │ │ │ ├── useCreateClassAttribute.ts │ │ │ │ ├── usePublishMeta.ts │ │ │ │ ├── useRootClasses.ts │ │ │ │ ├── useGetFirstParentUuids.ts │ │ │ │ ├── useCreateClassInnerId.ts │ │ │ │ ├── useChangeDiagram.ts │ │ │ │ ├── useChangeRelation.ts │ │ │ │ ├── useCreateRelationInnerId.ts │ │ │ │ ├── useExportModelJson.ts │ │ │ │ ├── useDeleteMethod.ts │ │ │ │ ├── useExportOrchestrationJson.ts │ │ │ │ ├── useDeleteAttribute.ts │ │ │ │ ├── useDeleteRelation.ts │ │ │ │ ├── useGetAllParentUuids.ts │ │ │ │ └── useIsElement.ts │ │ │ ├── PropertyPanel │ │ │ │ ├── ScriptInput │ │ │ │ │ └── style.less │ │ │ │ └── MethodPanel │ │ │ │ │ ├── ArgsInput │ │ │ │ │ ├── style.less │ │ │ │ │ └── LazyInput.tsx │ │ │ │ │ └── MethodTypeInput.tsx │ │ │ └── EmpertyCanvas.tsx │ │ ├── AppAuth │ │ │ ├── MenuAuthBoard │ │ │ │ └── style.less │ │ │ ├── PageAuthBoard │ │ │ │ └── style.less │ │ │ ├── AppAuthBoard │ │ │ │ └── index.tsx │ │ │ ├── recoil │ │ │ │ └── atoms.ts │ │ │ ├── hooks │ │ │ │ ├── useRoles.ts │ │ │ │ ├── model.ts │ │ │ │ ├── useGetCategoryPages.ts │ │ │ │ ├── useRole.ts │ │ │ │ ├── useParsePageComponents.ts │ │ │ │ ├── usePagesWithoutCategory.ts │ │ │ │ ├── useAuthPages.ts │ │ │ │ ├── useRoleName.ts │ │ │ │ ├── useAuthCategories.ts │ │ │ │ ├── useGetPackageCanAuthClasses.ts │ │ │ │ ├── useUpsertClassAuthConfig.ts │ │ │ │ ├── useQueryRoles.ts │ │ │ │ ├── useUpsertPropertyAuthConfig.ts │ │ │ │ ├── useUpsertComponentAuthConfig.ts │ │ │ │ ├── useQueryAppMenus.ts │ │ │ │ ├── useUpsertMenuAuthConfig.ts │ │ │ │ └── useQueryAppPages.ts │ │ │ ├── style.less │ │ │ ├── ModelAuthBoard │ │ │ │ ├── style.less │ │ │ │ └── IAuthRow.ts │ │ │ ├── IUiAuthConfig.ts │ │ │ └── RoleList │ │ │ │ └── style.less │ │ ├── AppDmn │ │ │ └── index.tsx │ │ ├── ApiBoard │ │ │ ├── trimServerUrl.ts │ │ │ └── index.less │ │ ├── AppConfig │ │ │ ├── MultLangForm │ │ │ │ └── LangResourceEditor │ │ │ │ │ └── style.less │ │ │ └── index.tsx │ │ ├── hooks │ │ │ ├── useEdittingAppUuid.ts │ │ │ ├── useRemoveApp.ts │ │ │ ├── useUpsertApp.ts │ │ │ ├── useLoginCheck.ts │ │ │ ├── useDeleteLangLocal.ts │ │ │ ├── useShowError.ts │ │ │ ├── useQueryAllTemplates.ts │ │ │ ├── useUpdatePage.ts │ │ │ ├── useQueryPage.ts │ │ │ ├── useQueryAppConfig.ts │ │ │ ├── useQueryApp.ts │ │ │ ├── useQueryLangLocales.ts │ │ │ └── useAppDevicePages.ts │ │ ├── ThemeRoot │ │ │ ├── theme.d.ts │ │ │ └── index.tsx │ │ ├── DesignerHeader │ │ │ └── AppEntryRouts.ts │ │ ├── AppDesignBoard │ │ │ └── inex.tsx │ │ └── index.tsx │ ├── bpmn │ │ ├── @types │ │ │ ├── diagram-js-minimap │ │ │ │ └── index.d.ts │ │ │ └── didi │ │ │ │ └── index.d.ts │ │ └── decorators │ │ │ └── inject.decorator.ts │ ├── datasource │ │ ├── index.ts │ │ ├── model │ │ │ ├── IQueryForm.ts │ │ │ ├── IOrderBy.ts │ │ │ ├── index.ts │ │ │ ├── IDataBindSource.ts │ │ │ ├── AssociationMeta.ts │ │ │ ├── EntityMeta.ts │ │ │ └── IFieldSource.ts │ │ ├── hooks │ │ │ ├── index.ts │ │ │ ├── IFragmentParams.ts │ │ │ ├── mapOrderBy.ts │ │ │ ├── usePackages.ts │ │ │ ├── useGetEntity.ts │ │ │ ├── useGetPackageRootEntities.ts │ │ │ ├── createObjectFieldNode.ts │ │ │ ├── getParentClasses.ts │ │ │ └── getChildEntities.ts │ │ └── recoil │ │ │ └── index.ts │ ├── enthooks │ │ ├── events │ │ │ ├── IRemoved.ts │ │ │ ├── IPosted.ts │ │ │ ├── IUpdated.ts │ │ │ └── index.ts │ │ ├── hooks │ │ │ ├── IQueryInput.ts │ │ │ ├── useMountRef.ts │ │ │ ├── index.ts │ │ │ ├── useQueryMe.ts │ │ │ ├── useLogout.ts │ │ │ ├── useImportApp.ts │ │ │ ├── useExportApp.ts │ │ │ └── useInstall.ts │ │ ├── index.ts │ │ └── awesome-graphql-client │ │ │ ├── util │ │ │ ├── assert.ts │ │ │ ├── isResponseJSON.ts │ │ │ ├── types.ts │ │ │ ├── gql.ts │ │ │ └── formatGetRequestUrl.ts │ │ │ └── index.ts │ ├── dashboard │ │ ├── Spring.tsx │ │ ├── Routes.ts │ │ ├── Services │ │ │ └── index.tsx │ │ ├── StyledThemeRoot.tsx │ │ ├── ConfigRoot.tsx │ │ └── AppManager │ │ │ ├── hooks │ │ │ └── useAppOpenFile.ts │ │ │ └── AppModal │ │ │ └── CreateAppDialog.tsx │ ├── common │ │ ├── CenterSpin │ │ │ ├── style.less │ │ │ └── index.tsx │ │ ├── ResizableColumn │ │ │ └── style.less │ │ ├── ListConentLayout │ │ │ ├── style.less │ │ │ └── index.tsx │ │ ├── ModelBoard │ │ │ ├── PropertyBox │ │ │ │ ├── ToolbarTitle.tsx │ │ │ │ ├── ToolbarArea.tsx │ │ │ │ └── index.tsx │ │ │ ├── ModelToolbar │ │ │ │ ├── index.tsx │ │ │ │ └── style.less │ │ │ └── style.less │ │ └── SvgIcon.tsx │ ├── model │ │ ├── snapshot.ts │ │ ├── role.ts │ │ ├── file.ts │ │ ├── lang.ts │ │ ├── menu.ts │ │ ├── index.ts │ │ ├── material.ts │ │ ├── uiframe.ts │ │ ├── user.ts │ │ ├── notification.ts │ │ ├── plugin.ts │ │ ├── page.ts │ │ └── template.ts │ ├── shared │ │ ├── BaseDataType.ts │ │ ├── MultLangWidget │ │ │ └── index.tsx │ │ ├── formatFileSize.ts │ │ └── index.ts │ ├── theme.d.ts │ ├── i18n │ │ ├── useBundleTranslations.ts │ │ └── registerResourceBundle.ts │ ├── setupTests.ts │ ├── variables.less │ ├── App.test.tsx │ ├── recoil │ │ └── atoms.ts │ ├── reportWebVitals.ts │ ├── plugins │ │ └── framelayouts │ │ │ └── pc │ │ │ └── Container │ │ │ └── view │ │ │ ├── style.less │ │ │ └── index.tsx │ ├── icons │ │ └── PlugIcon.tsx │ ├── hooks │ │ └── useQueryApps.ts │ ├── Login │ │ └── LoggedInPanel.tsx │ ├── index.css │ ├── index.tsx │ ├── consts.ts │ └── Install │ │ └── Installed.tsx ├── craco.config.js ├── .gitignore └── tsconfig.json ├── backend-libs ├── README.md └── orm │ └── README.md ├── frontend-libs ├── README.md └── modelhooks │ └── README.md ├── services ├── README.md ├── models │ ├── modules │ │ ├── README.md │ │ └── app │ │ │ ├── convertFieldsArray.go │ │ │ ├── middleware.go │ │ │ ├── cache.go │ │ │ └── system-app.go │ ├── errorx │ │ ├── consts.go │ │ ├── error.go │ │ └── format.go │ ├── config_example.yaml │ ├── consts │ │ └── meta.go │ ├── README.md │ ├── .gitignore │ ├── Dockerfile │ ├── .vscode │ │ └── launch.json │ ├── contexts │ │ └── contexts.go │ ├── logs │ │ └── consts.go │ └── middlewares │ │ └── cors.go ├── report │ └── README.md ├── workflow │ └── README.md ├── storage │ └── README.md ├── authorization │ └── README.md ├── events │ └── README.md ├── authentication │ └── README.md └── schedule │ ├── runner │ ├── http-task.go │ └── job.go │ ├── resolver │ ├── README.md │ ├── types.go │ ├── resolver.go │ ├── query.go │ └── mutation.go │ ├── config_example.yaml │ ├── config.yaml │ ├── global │ └── global.go │ ├── entities │ ├── TaskConfig.go │ ├── enums.go │ └── Task.go │ ├── .gitignore │ ├── Dockerfile │ ├── .vscode │ └── launch.json │ └── README.md ├── .gitattributes ├── gateway ├── README.md ├── .vscode │ └── launch.json ├── Dockerfile ├── main.go ├── middlewares │ ├── appheader.go │ └── cors.go └── go.mod └── federation ├── accounts ├── graph │ ├── schema.graphqls │ ├── resolver.go │ ├── model │ │ └── models_gen.go │ ├── handler.go │ └── schema.resolvers.go └── server.go ├── tools.go ├── README.md ├── products ├── graph │ ├── resolver.go │ ├── variables.go │ ├── model │ │ └── models_gen.go │ ├── schema.graphqls │ └── products.go └── server.go ├── reviews ├── graph │ ├── resolver.go │ ├── schema.graphqls │ ├── model │ │ └── models_gen.go │ ├── handler.go │ └── reviews.go └── server.go └── start.sh /README.md: -------------------------------------------------------------------------------- 1 | 乐搭低代码平台 -------------------------------------------------------------------------------- /studio/README.md: -------------------------------------------------------------------------------- 1 | 前端客户端 -------------------------------------------------------------------------------- /backend-libs/README.md: -------------------------------------------------------------------------------- 1 | 后端类库 -------------------------------------------------------------------------------- /frontend-libs/README.md: -------------------------------------------------------------------------------- 1 | 前端类库 -------------------------------------------------------------------------------- /services/README.md: -------------------------------------------------------------------------------- 1 | 微服务形式的引擎,核心,内置 -------------------------------------------------------------------------------- /services/models/modules/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /services/report/README.md: -------------------------------------------------------------------------------- 1 | 报表引擎 -------------------------------------------------------------------------------- /services/workflow/README.md: -------------------------------------------------------------------------------- 1 | 工作流服务 -------------------------------------------------------------------------------- /backend-libs/orm/README.md: -------------------------------------------------------------------------------- 1 | ORM库 2 | -------------------------------------------------------------------------------- /studio/.env: -------------------------------------------------------------------------------- 1 | GENERATE_SOURCEMAP=false -------------------------------------------------------------------------------- /frontend-libs/modelhooks/README.md: -------------------------------------------------------------------------------- 1 | models接口存取钩子 -------------------------------------------------------------------------------- /services/storage/README.md: -------------------------------------------------------------------------------- 1 | 内容存储引擎 2 | 图片、视频、文件等 -------------------------------------------------------------------------------- /studio/public/locales/de/translation.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /studio/public/locales/zh/translation.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /services/authorization/README.md: -------------------------------------------------------------------------------- 1 | 鉴权服务 2 | 只处理鉴权,不处理登录 -------------------------------------------------------------------------------- /services/events/README.md: -------------------------------------------------------------------------------- 1 | 事件引擎 2 | 前端可以根据通知类型,再去拉数据 -------------------------------------------------------------------------------- /services/authentication/README.md: -------------------------------------------------------------------------------- 1 | 身份验证服务 2 | 只处理登录,不处理鉴权 -------------------------------------------------------------------------------- /services/schedule/runner/http-task.go: -------------------------------------------------------------------------------- 1 | package runner 2 | -------------------------------------------------------------------------------- /studio/src/plugin-sdk/icon/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./model" -------------------------------------------------------------------------------- /services/schedule/resolver/README.md: -------------------------------------------------------------------------------- 1 | 本目录存放所有的Resolves,内部的代码不会被覆盖 -------------------------------------------------------------------------------- /studio/src/plugin-sdk/locales/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./FormGridLocales" -------------------------------------------------------------------------------- /studio/src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/IModeler.ts: -------------------------------------------------------------------------------- 1 | export interface IModeler{ 2 | 3 | } -------------------------------------------------------------------------------- /studio/src/plugin-sdk/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./useParseLangMessage" 2 | -------------------------------------------------------------------------------- /services/schedule/resolver/types.go: -------------------------------------------------------------------------------- 1 | package resolver 2 | 3 | type ID = string 4 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /gateway/README.md: -------------------------------------------------------------------------------- 1 | docker build --pull --rm -f "Dockerfile" -t idlewater2/gateway:v0.0.1 "." -------------------------------------------------------------------------------- /studio/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/logo.png -------------------------------------------------------------------------------- /services/schedule/resolver/resolver.go: -------------------------------------------------------------------------------- 1 | package resolver 2 | 3 | type Resolver struct{} 4 | 5 | -------------------------------------------------------------------------------- /studio/public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/favicon.png -------------------------------------------------------------------------------- /studio/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/logo192.png -------------------------------------------------------------------------------- /studio/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/logo512.png -------------------------------------------------------------------------------- /studio/src/bpmn/@types/diagram-js-minimap/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'diagram-js-minimap' { 2 | } -------------------------------------------------------------------------------- /studio/public/img/bird.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/bird.png -------------------------------------------------------------------------------- /studio/public/img/bird2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/bird2.png -------------------------------------------------------------------------------- /studio/public/img/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/blank.png -------------------------------------------------------------------------------- /studio/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /services/models/errorx/consts.go: -------------------------------------------------------------------------------- 1 | package errorx 2 | 3 | const CODE_LOGIN_EXPIRED string = "entix.0001" 4 | -------------------------------------------------------------------------------- /studio/public/img/install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/install.png -------------------------------------------------------------------------------- /studio/public/img/install1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/install1.png -------------------------------------------------------------------------------- /studio/public/img/install2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/install2.png -------------------------------------------------------------------------------- /studio/public/img/install3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/install3.png -------------------------------------------------------------------------------- /studio/public/img/login1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/login1.png -------------------------------------------------------------------------------- /studio/public/img/login2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/login2.png -------------------------------------------------------------------------------- /studio/public/img/mobile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/mobile.png -------------------------------------------------------------------------------- /studio/public/img/security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/security.png -------------------------------------------------------------------------------- /studio/public/img/website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/website.png -------------------------------------------------------------------------------- /studio/public/img/login1-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/login1-big.png -------------------------------------------------------------------------------- /studio/src/datasource/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./hooks"; 2 | export * from "./model"; 3 | export * from "./recoil"; -------------------------------------------------------------------------------- /studio/public/img/background1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/background1.jpg -------------------------------------------------------------------------------- /studio/public/img/background2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/background2.jpg -------------------------------------------------------------------------------- /studio/public/img/design-team.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/design-team.png -------------------------------------------------------------------------------- /studio/public/img/install1-big.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codebdy/leda/HEAD/studio/public/img/install1-big.png -------------------------------------------------------------------------------- /studio/src/designer/AppUml/EntityTree/PackageLabel/style.less: -------------------------------------------------------------------------------- 1 | .token-script-editor{ 2 | min-height: 300px; 3 | } 4 | -------------------------------------------------------------------------------- /studio/src/enthooks/events/IRemoved.ts: -------------------------------------------------------------------------------- 1 | export interface IRemoved { 2 | entity: string, 3 | ids: number[], 4 | } -------------------------------------------------------------------------------- /studio/src/datasource/model/IQueryForm.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface IQueryForm { 3 | [key: string]: any | any[]; 4 | } 5 | -------------------------------------------------------------------------------- /studio/src/plugin-sdk/contexts/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./app" 2 | export * from "./desinger" 3 | export * from "./login" 4 | -------------------------------------------------------------------------------- /services/schedule/resolver/query.go: -------------------------------------------------------------------------------- 1 | package resolver 2 | 3 | func (*Resolver) Hello() string { 4 | return "Hello query!" 5 | } 6 | -------------------------------------------------------------------------------- /studio/src/datasource/model/IOrderBy.ts: -------------------------------------------------------------------------------- 1 | export interface IOrderBy { 2 | field: string, 3 | order: "desc" | "asc" | undefined 4 | } -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/MenuAuthBoard/style.less: -------------------------------------------------------------------------------- 1 | .menu-auth-content{ 2 | flex: 1; 3 | overflow: auto; 4 | padding: 0 16px; 5 | } -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/PageAuthBoard/style.less: -------------------------------------------------------------------------------- 1 | .page-auth-content{ 2 | flex: 1; 3 | overflow: auto; 4 | padding: 0 16px; 5 | } -------------------------------------------------------------------------------- /studio/src/plugin-sdk/icon/model.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface IIcon { 3 | iconKey?: string; 4 | svgString?: string; 5 | } 6 | 7 | 8 | -------------------------------------------------------------------------------- /studio/src/plugin-sdk/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./action" 2 | export * from "./IDataSourceableProps" 3 | export * from "./IMenuNode" -------------------------------------------------------------------------------- /studio/src/dashboard/Spring.tsx: -------------------------------------------------------------------------------- 1 | import styled from "styled-components"; 2 | 3 | export const Spring = styled.div` 4 | flex:1; 5 | `; 6 | -------------------------------------------------------------------------------- /studio/src/datasource/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./AssociationMeta"; 2 | export * from "./EntityMeta"; 3 | export * from "./IDataBindSource"; -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/nodeInitSize.ts: -------------------------------------------------------------------------------- 1 | 2 | export const NODE_INIT_SIZE = { 3 | width: 180, 4 | height: 120, 5 | }; 6 | -------------------------------------------------------------------------------- /studio/src/plugin-sdk/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./contexts" 2 | export * from "./hooks" 3 | export * from "./locales" 4 | export * from "./model" 5 | -------------------------------------------------------------------------------- /studio/src/dashboard/Routes.ts: -------------------------------------------------------------------------------- 1 | export enum DashboardRoutes { 2 | AppManager = "app-manager", 3 | Services = "services", 4 | Config = "config" 5 | } -------------------------------------------------------------------------------- /services/schedule/config_example.yaml: -------------------------------------------------------------------------------- 1 | database: your database 2 | driver: mysql 3 | host: localhost 4 | password: your password 5 | port: "3306" 6 | user: root -------------------------------------------------------------------------------- /studio/src/enthooks/hooks/IQueryInput.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface IQueryInput { 3 | gql?: string; 4 | params?: any; 5 | depEntityNames?: string[]; 6 | } 7 | -------------------------------------------------------------------------------- /studio/src/enthooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./awesome-graphql-client"; 2 | export * from "./hooks"; 3 | export * from "./context"; 4 | export * from "./EntiRoot"; -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/CodeMeta.ts: -------------------------------------------------------------------------------- 1 | export interface CodeMeta { 2 | uuid: string; 3 | name: string; 4 | description?: string; 5 | script?: string; 6 | } -------------------------------------------------------------------------------- /services/schedule/config.yaml: -------------------------------------------------------------------------------- 1 | database: caa 2 | driver: mysql 3 | host: host.docker.internal 4 | password: RxDragDb 5 | port: "3306" 6 | user: root 7 | migration: install -------------------------------------------------------------------------------- /studio/src/dashboard/Services/index.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react" 2 | 3 | export const Services = memo(() => { 4 | return (
5 | Services 6 |
) 7 | }) -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/OrchestrationMeta.ts: -------------------------------------------------------------------------------- 1 | import { MethodMeta } from "./MethodMeta"; 2 | 3 | export interface OrchestrationMeta extends MethodMeta { 4 | 5 | } -------------------------------------------------------------------------------- /federation/accounts/graph/schema.graphqls: -------------------------------------------------------------------------------- 1 | extend type Query { 2 | me: User 3 | } 4 | 5 | type User @key(fields: "id") { 6 | id: ID! 7 | username: String! 8 | } 9 | -------------------------------------------------------------------------------- /services/models/config_example.yaml: -------------------------------------------------------------------------------- 1 | database: your database 2 | driver: mysql 3 | host: localhost 4 | password: your password 5 | port: "3306" 6 | user: root 7 | migration: install -------------------------------------------------------------------------------- /studio/src/enthooks/events/IPosted.ts: -------------------------------------------------------------------------------- 1 | export interface IPosted { 2 | entity: string, 3 | requested?: { [entity: string]: any }; 4 | response?: { [entity: string]: any }; 5 | } -------------------------------------------------------------------------------- /studio/src/datasource/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./useBuildMeta"; 2 | export * from "./useGetPackageRootEntities"; 3 | export * from "./usePackages"; 4 | export * from "./useDataQuery"; -------------------------------------------------------------------------------- /studio/src/datasource/model/IDataBindSource.ts: -------------------------------------------------------------------------------- 1 | export interface IDataBindSource { 2 | entityUuid?: string; 3 | entityName?: string; 4 | expression?: string; 5 | variables?: any; 6 | } -------------------------------------------------------------------------------- /studio/src/designer/AppDmn/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { memo } from "react"; 3 | 4 | export const AppDmn = memo(()=>{ 5 | return ( 6 | <> 7 | 8 | ) 9 | }) -------------------------------------------------------------------------------- /studio/src/common/CenterSpin/style.less: -------------------------------------------------------------------------------- 1 | .center-loading-spin{ 2 | width: 100%; 3 | height: 100%; 4 | flex:1; 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | } -------------------------------------------------------------------------------- /studio/src/enthooks/awesome-graphql-client/util/assert.ts: -------------------------------------------------------------------------------- 1 | export function assert(condition: any, msg: string): asserts condition { 2 | if (!condition) { 3 | throw new Error(msg) 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /studio/src/plugin-sdk/model/IDataSourceableProps.ts: -------------------------------------------------------------------------------- 1 | import { IDataBindSource } from "datasource"; 2 | 3 | 4 | export interface IDataSourceableProps { 5 | dataBind?: IDataBindSource; 6 | } 7 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/consts.ts: -------------------------------------------------------------------------------- 1 | export const CONST_CANVAS_CLICK:string = "canvas_click" 2 | 3 | export const CANVAS_BACKGROUND_COLOR = "#f0f2f5"; 4 | export const CLASS_BACKGROUND_COLOR = "#fff"; -------------------------------------------------------------------------------- /studio/src/model/snapshot.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | 3 | export interface ISnapshot{ 4 | id:ID; 5 | version: string; 6 | description?: string; 7 | createdAt: Date; 8 | instanceId: ID; 9 | } -------------------------------------------------------------------------------- /federation/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | package tools 5 | 6 | import ( 7 | _ "github.com/99designs/gqlgen" 8 | _ "github.com/99designs/gqlgen/graphql/introspection" 9 | ) 10 | -------------------------------------------------------------------------------- /services/models/consts/meta.go: -------------------------------------------------------------------------------- 1 | package consts 2 | 3 | const META_ENTITY_NAME = "Meta" 4 | const APP_ENTITY_NAME = "App" 5 | 6 | // const SERVICE_ENTITY_NAME = "Service" 7 | // const USER_ENTITY_NAME = "User" 8 | -------------------------------------------------------------------------------- /services/schedule/global/global.go: -------------------------------------------------------------------------------- 1 | package global 2 | 3 | import ( 4 | "github.com/codebdy/leda-service-sdk/system" 5 | ) 6 | 7 | const SERVICE_NAME = "schedule" 8 | 9 | var ServiceMeta *system.Meta 10 | -------------------------------------------------------------------------------- /studio/src/common/ResizableColumn/style.less: -------------------------------------------------------------------------------- 1 | .drawer-resizing{ 2 | -webkit-user-select: none; 3 | -moz-user-select: none; 4 | -ms-user-select: none; 5 | user-select: none; 6 | cursor: 'w-resize'; 7 | } 8 | -------------------------------------------------------------------------------- /studio/src/datasource/hooks/IFragmentParams.ts: -------------------------------------------------------------------------------- 1 | import { IOrderBy } from "../model/IOrderBy"; 2 | 3 | export interface IFragmentParams { 4 | gql?: string; 5 | variables?: any; 6 | orderBys?: IOrderBy[]; 7 | } 8 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/AppAuthBoard/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { memo } from "react" 3 | 4 | export const AppAuthBoard = memo(()=>{ 5 | return ( 6 |
AppAuthBoard
7 | ) 8 | }) -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/recoil/atoms.ts: -------------------------------------------------------------------------------- 1 | import { atom } from "recoil"; 2 | import { IRole } from "model"; 3 | 4 | export const authRolesState = atom({ 5 | key: "authRoles", 6 | default: [], 7 | }) 8 | -------------------------------------------------------------------------------- /studio/src/model/role.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | 3 | export interface IRole { 4 | id: ID, 5 | name: string, 6 | } 7 | 8 | export interface IRoleInput { 9 | id?: ID, 10 | name?: string, 11 | } -------------------------------------------------------------------------------- /federation/README.md: -------------------------------------------------------------------------------- 1 | # Federation Demo 2 | 3 | ## Getting started 4 | 1. Install go modules 5 | ```shell 6 | go mod download 7 | ``` 8 | 2. Run start script 9 | ``` 10 | chmod +x start.sh 11 | ./start.sh 12 | ``` -------------------------------------------------------------------------------- /studio/src/common/ListConentLayout/style.less: -------------------------------------------------------------------------------- 1 | @import "../../variables.less"; 2 | 3 | .appx-list-content-layout{ 4 | flex: 1; 5 | display: flex; 6 | flex-flow: row; 7 | height: calc(100vh - @toolbarHeight); 8 | } -------------------------------------------------------------------------------- /studio/src/designer/ApiBoard/trimServerUrl.ts: -------------------------------------------------------------------------------- 1 | import _ from "lodash"; 2 | 3 | export function trimServerUrl(url:string){ 4 | if(_.endsWith(url, '/')){ 5 | return _.trimEnd(url, '/'); 6 | } 7 | return url; 8 | } -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useRoles.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { authRolesState } from "../recoil/atoms"; 3 | 4 | export function useRoles(){ 5 | return useRecoilValue(authRolesState); 6 | } -------------------------------------------------------------------------------- /studio/src/model/file.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | 3 | export interface IFile { 4 | id: ID; 5 | thumbUrl: string; 6 | } 7 | 8 | export interface IFileInput { 9 | id?: ID; 10 | thumbUrl?: string; 11 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/recoil/LineAction.ts: -------------------------------------------------------------------------------- 1 | import { RelationType } from "../meta/RelationMeta"; 2 | 3 | export interface LineAction { 4 | relationType: RelationType; 5 | sourceNodeId: string; 6 | tempEdgeId?: string; 7 | } -------------------------------------------------------------------------------- /federation/accounts/graph/resolver.go: -------------------------------------------------------------------------------- 1 | // This file will not be regenerated automatically. 2 | // 3 | // It serves as dependency injection for your app, add any dependencies you require here. 4 | package graph 5 | 6 | type Resolver struct{} 7 | -------------------------------------------------------------------------------- /federation/products/graph/resolver.go: -------------------------------------------------------------------------------- 1 | // This file will not be regenerated automatically. 2 | // 3 | // It serves as dependency injection for your app, add any dependencies you require here. 4 | package graph 5 | 6 | type Resolver struct{} 7 | -------------------------------------------------------------------------------- /federation/reviews/graph/resolver.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | // This file will not be regenerated automatically. 4 | // 5 | // It serves as dependency injection for your app, add any dependencies you require here. 6 | 7 | type Resolver struct{} 8 | -------------------------------------------------------------------------------- /studio/src/enthooks/events/IUpdated.ts: -------------------------------------------------------------------------------- 1 | export type UpdateData = { [entityName: string]: { data: T[] } }; 2 | 3 | export interface IUpdated{ 4 | entity: string, 5 | requested: UpdateData; 6 | response: { [entity: string]: any }; 7 | } -------------------------------------------------------------------------------- /studio/src/designer/AppConfig/MultLangForm/LangResourceEditor/style.less: -------------------------------------------------------------------------------- 1 | .lang-resource-table{ 2 | .table-toolbar{ 3 | display: flex; 4 | justify-content: space-between; 5 | .search-input{ 6 | width: 300px; 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /studio/src/shared/BaseDataType.ts: -------------------------------------------------------------------------------- 1 | export enum BaseDataType { 2 | ID = "ID", 3 | Int = "Int", 4 | Float = "Float", 5 | Boolean = "Boolean", 6 | String = "String", 7 | Date = "Date", 8 | Enum = "Enum", 9 | Range = "Range", 10 | } -------------------------------------------------------------------------------- /studio/src/datasource/model/AssociationMeta.ts: -------------------------------------------------------------------------------- 1 | import { AssociationType } from "./IFieldSource"; 2 | 3 | export interface AssociationMeta { 4 | name: string; 5 | label?: string; 6 | typeUuid: string; 7 | associationType: AssociationType, 8 | } 9 | -------------------------------------------------------------------------------- /studio/src/theme.d.ts: -------------------------------------------------------------------------------- 1 | import 'styled-components'; 2 | import { GlobalToken } from "antd/es/theme/interface"; 3 | 4 | // and extend them! 5 | declare module 'styled-components' { 6 | export interface DefaultTheme { 7 | token?: GlobalToken; 8 | } 9 | } -------------------------------------------------------------------------------- /studio/src/designer/hooks/useEdittingAppUuid.ts: -------------------------------------------------------------------------------- 1 | import { useParams } from "react-router-dom"; 2 | import { SYSTEM_APP_ID } from "../../consts"; 3 | 4 | export function useEdittingAppId() { 5 | const { appId = SYSTEM_APP_ID } = useParams(); 6 | 7 | return appId; 8 | } -------------------------------------------------------------------------------- /studio/src/bpmn/@types/didi/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'didi' { 2 | export class Injector { 3 | get(name: string, strict: boolean): any; 4 | } 5 | 6 | export interface DidiModule { 7 | [id: string]: ['type' | 'factory' | 'value', any]; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /studio/src/designer/ThemeRoot/theme.d.ts: -------------------------------------------------------------------------------- 1 | import 'styled-components'; 2 | import { GlobalToken } from "antd/es/theme/interface"; 3 | 4 | // and extend them! 5 | declare module 'styled-components' { 6 | export interface DefaultTheme { 7 | token?: GlobalToken; 8 | } 9 | } -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/style.less: -------------------------------------------------------------------------------- 1 | @import "../../variables.less"; 2 | 3 | .appx-auth-board{ 4 | background-color: @backgrounColor; 5 | } 6 | 7 | .auth-breadcrumb{ 8 | padding: 8px 16px; 9 | height: 40px; 10 | display: flex; 11 | align-items: center; 12 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/plugins/palette/index.ts: -------------------------------------------------------------------------------- 1 | import CustomPaletteProvider from "./CustomPaletteProvider"; 2 | 3 | const palette = { 4 | __init__: ["customPaletteProvider"], 5 | customPaletteProvider: ["type", CustomPaletteProvider] 6 | }; 7 | 8 | export default palette -------------------------------------------------------------------------------- /studio/src/i18n/useBundleTranslations.ts: -------------------------------------------------------------------------------- 1 | import { useTranslation } from "react-i18next"; 2 | 3 | export function useBundleTranslations(ns: string) { 4 | const { i18n } = useTranslation(); 5 | return useTranslation(i18n.hasResourceBundle(i18n.language, ns) ? ns : undefined) 6 | } -------------------------------------------------------------------------------- /federation/accounts/graph/model/models_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. 2 | 3 | package model 4 | 5 | type User struct { 6 | ID string `json:"id"` 7 | Username string `json:"username"` 8 | } 9 | 10 | func (User) IsEntity() {} 11 | -------------------------------------------------------------------------------- /federation/products/graph/variables.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | var ( 8 | randomnessEnabled = true 9 | minPrice = 10 10 | maxPrice = 1499 11 | currentPrice = minPrice 12 | updateInterval = time.Second 13 | ) 14 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/style.less: -------------------------------------------------------------------------------- 1 | @import "../../variables.less"; 2 | 3 | .model-minimap{ 4 | position: absolute; 5 | z-index: 1; 6 | bottom: 3px; 7 | left: 3px; 8 | width: 140px; 9 | height: 110px; 10 | border-radius: 5px; 11 | overflow: hidden; 12 | } 13 | -------------------------------------------------------------------------------- /studio/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom'; 6 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/plugins/context-pad/index.ts: -------------------------------------------------------------------------------- 1 | import CustomContextPadProvider from "./CustomContextPadProvider"; 2 | 3 | const pad= { 4 | __init__: ["customContextPadProvider"], 5 | customContextPadProvider: ["type", CustomContextPadProvider] 6 | }; 7 | 8 | export default pad -------------------------------------------------------------------------------- /studio/src/designer/hooks/useRemoveApp.ts: -------------------------------------------------------------------------------- 1 | import { IDeleteOptions, useDeleteById } from "../../enthooks/hooks/useDeleteById"; 2 | import { IApp } from "../../model"; 3 | 4 | export function useRemoveApp(options?: IDeleteOptions) { 5 | return useDeleteById("App", options) 6 | } -------------------------------------------------------------------------------- /studio/src/enthooks/awesome-graphql-client/util/isResponseJSON.ts: -------------------------------------------------------------------------------- 1 | import { RequestResult } from './types' 2 | 3 | export const isResponseJSON = (response: { 4 | headers: RequestResult['headers'] 5 | }): boolean => (response.headers.get('Content-Type') || '').includes('application/json') 6 | -------------------------------------------------------------------------------- /studio/src/variables.less: -------------------------------------------------------------------------------- 1 | @borderColor:rgba(0, 0, 0, 0.06); 2 | @contentPadding:0 160px; 3 | @appManageBarHeight: 64px; 4 | @floatBoxShadow: 8px 8px 14px 0 rgb(25 42 70 / 11%); 5 | @backgrounColor: #fff; 6 | @toolbarHeight: 64px; 7 | @canvasBackgroundColor:#f0f2f5; 8 | @primaryColor: #5d78ff; 9 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/X6NodeMeta.ts: -------------------------------------------------------------------------------- 1 | export interface X6NodeMeta{ 2 | id: string; 3 | /** 节点x坐标 */ 4 | x?: number; 5 | /** 节点y坐标 */ 6 | y?: number; 7 | /** 节点宽度 */ 8 | width?: number; 9 | /** 节点高度 */ 10 | height?: number; 11 | 12 | diagramUuid: string; 13 | } -------------------------------------------------------------------------------- /studio/src/i18n/registerResourceBundle.ts: -------------------------------------------------------------------------------- 1 | import i18n from './index' 2 | 3 | export function registerResourceBundle(nameSpace: string, bundles: { [key: string]: any },) { 4 | for (const key of Object.keys(bundles)) { 5 | i18n.addResourceBundle(key, nameSpace, bundles[key]); 6 | }; 7 | } 8 | -------------------------------------------------------------------------------- /studio/src/plugin-sdk/contexts/login.ts: -------------------------------------------------------------------------------- 1 | import { createContext, useContext } from "react"; 2 | import { IUser } from "enthooks/hooks/useQueryMe"; 3 | 4 | export const UserContext = createContext(undefined); 5 | 6 | export function useMe(){ 7 | return useContext(UserContext); 8 | } -------------------------------------------------------------------------------- /studio/src/designer/hooks/useUpsertApp.ts: -------------------------------------------------------------------------------- 1 | 2 | import { IPostOptions, usePostOne } from '../../enthooks/hooks/usePostOne'; 3 | import { IApp, IAppInput } from '../../model'; 4 | 5 | export function useUpsertApp(options?: IPostOptions) { 6 | return usePostOne("App", options) 7 | } -------------------------------------------------------------------------------- /studio/src/datasource/hooks/mapOrderBy.ts: -------------------------------------------------------------------------------- 1 | 2 | export const mapOrderBy = (orderBy?: "ascend" | "descend"): 'asc' | 'desc' | undefined => { 3 | if (orderBy === "ascend") { 4 | return "asc"; 5 | } else if (orderBy === "descend") { 6 | return "desc"; 7 | } 8 | return orderBy; 9 | }; 10 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/plugins/replace/index.ts: -------------------------------------------------------------------------------- 1 | import CustomReplaceMenuProvider from "./CustomReplaceMenuProvider"; 2 | 3 | const provider = { 4 | __init__: ["customReplaceMenuProvider"], 5 | customReplaceMenuProvider: ["type", CustomReplaceMenuProvider] 6 | }; 7 | 8 | export default provider 9 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/items/IdItem.tsx: -------------------------------------------------------------------------------- 1 | import { Form, Input } from "antd"; 2 | import React from "react"; 3 | 4 | export const IdItem = () => { 5 | return ( 6 | 10 | 11 | 12 | ) 13 | } -------------------------------------------------------------------------------- /services/schedule/entities/TaskConfig.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | type TaskConfig struct { 4 | RequestType string `json:"requestType"` 5 | Url string `json:"url"` 6 | Gql string `json:"gql"` 7 | Params interface{} `json:"params"` 8 | Headers interface{} `json:"headers"` 9 | } 10 | -------------------------------------------------------------------------------- /studio/src/designer/DesignerHeader/AppEntryRouts.ts: -------------------------------------------------------------------------------- 1 | export enum AppEntryRouts { 2 | Config = "config", 3 | Ui = "ui", 4 | AppUis = "app-uis", 5 | Frame = "frame", 6 | Bpmn = "bpmn", 7 | Dmn = "dmn", 8 | Model = "model", 9 | Uml = "uml", 10 | Api = "api", 11 | Auth = "auth", 12 | Plugins = "plugins", 13 | } -------------------------------------------------------------------------------- /studio/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, screen } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | render(); 7 | const linkElement = screen.getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /studio/src/datasource/hooks/usePackages.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { useSelectedAppId } from "plugin-sdk/contexts/desinger"; 3 | import { packagesState } from "../recoil"; 4 | 5 | export function usePackages(){ 6 | const appId = useSelectedAppId(); 7 | 8 | return useRecoilValue(packagesState(appId)); 9 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useProcesses.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { useDesignerParams } from "plugin-sdk/contexts/desinger"; 3 | import { processesState } from "../recoil/atoms"; 4 | 5 | export function useProcesses() { 6 | const { app } = useDesignerParams() 7 | return useRecoilValue(processesState(app?.uuid)) 8 | } -------------------------------------------------------------------------------- /federation/products/graph/model/models_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. 2 | 3 | package model 4 | 5 | type Product struct { 6 | Upc string `json:"upc"` 7 | Name string `json:"name"` 8 | Price int `json:"price"` 9 | InStock int `json:"inStock"` 10 | } 11 | 12 | func (Product) IsEntity() {} 13 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useCategories.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { useDesignerParams } from "plugin-sdk/contexts/desinger"; 3 | import { categoriesState } from "../recoil/atoms"; 4 | 5 | export function useCategories() { 6 | const { app } = useDesignerParams() 7 | return useRecoilValue(categoriesState(app?.uuid)) 8 | } -------------------------------------------------------------------------------- /studio/src/enthooks/hooks/useMountRef.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | export function useMountRef(){ 4 | const mountRef = useRef(false); 5 | 6 | useEffect(() => { 7 | mountRef.current = true; 8 | return () => { 9 | mountRef.current = false; 10 | }; 11 | }, []); 12 | 13 | return mountRef; 14 | } -------------------------------------------------------------------------------- /services/schedule/entities/enums.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | const ( 4 | TASK_STATUS_ERROR string = "Error" 5 | TASK_STATUS_STOPED string = "Stoped" 6 | TASK_STATUS_RUNNING string = "Running" 7 | 8 | REQUEST_TYPE_HTTP_GET string = "HttpGet" 9 | REQUEST_TYPE_HTTP_POST string = "HttpPost" 10 | REQUEST_TYPE_GRAPHQL string = "Graphql" 11 | ) 12 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useClass.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { ID } from "shared"; 3 | import { classesState } from "../recoil/atoms"; 4 | 5 | export function useClass(uuid: string, appId: ID) { 6 | const entites = useRecoilValue(classesState(appId)); 7 | 8 | return entites.find((cls) => cls.uuid === uuid); 9 | } 10 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/elements/IElement.ts: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export interface IItemGroup { 4 | title: string, 5 | key: string, 6 | items: React.ReactNode, 7 | } 8 | 9 | export interface IElement { 10 | type?: string; 11 | name?: string | false; 12 | icon?: React.ReactElement, 13 | itemGroups?: IItemGroup[], 14 | } -------------------------------------------------------------------------------- /services/models/README.md: -------------------------------------------------------------------------------- 1 | 模型引擎 2 | 3 | docker内连宿主机mysql host.docker.internal 4 | 5 | 创建镜像: 6 | docker build --pull --rm -f "Dockerfile" -t idlewater2/models:v0.0.2 "." 7 | 8 | 创建容器 9 | docker create -p 4000:4000 --name models idlewater2/models:v0.0.1 10 | 11 | 创建标签 12 | docker tag $mageId idlewater2/models 13 | 14 | 推送镜像 15 | docker push idlewater2/models:v0.0.1 -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useParseRelationUuid.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { useCallback } from 'react'; 3 | 4 | export function useParseRelationUuid(appId: ID) { 5 | const parseUuid = useCallback((uuid: string):string => { 6 | const [, relationUuid] = uuid.split(","); 7 | return relationUuid 8 | }, []) 9 | 10 | return parseUuid 11 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/ClassView/useMountRef.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | 3 | export function useMountRef(){ 4 | const mountRef = useRef(false); 5 | 6 | useEffect(() => { 7 | mountRef.current = true; 8 | return () => { 9 | mountRef.current = false; 10 | }; 11 | }, []); 12 | 13 | return mountRef; 14 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/getGraphSize.ts: -------------------------------------------------------------------------------- 1 | export function getGraphSize():{width:number, height:number}{ 2 | const containerDiv = document.getElementById('container')||undefined; 3 | const size = { 4 | width: containerDiv?.getBoundingClientRect().width||800, 5 | height: containerDiv?.getBoundingClientRect().height||600 - 10, 6 | } 7 | 8 | return size; 9 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/PackageMeta.ts: -------------------------------------------------------------------------------- 1 | export enum PackageStereoType{ 2 | Normal = 'Normal', 3 | ThirdParty = 'ThirdParty' 4 | } 5 | 6 | /** 7 | * 包的元数据 8 | */ 9 | export interface PackageMeta{ 10 | uuid: string; 11 | name: string; 12 | system?: boolean; 13 | sharable?: boolean; 14 | stereoType?: PackageStereoType; 15 | tokenScript?: string; 16 | } -------------------------------------------------------------------------------- /services/models/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | config.yaml 15 | uploads 16 | temp-datas 17 | templates 18 | downloads 19 | plugins 20 | debug.log 21 | -------------------------------------------------------------------------------- /services/schedule/.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | config.yaml 15 | uploads 16 | temp-datas 17 | templates 18 | downloads 19 | plugins 20 | debug.log 21 | -------------------------------------------------------------------------------- /services/models/modules/app/convertFieldsArray.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import "github.com/graphql-go/graphql" 4 | 5 | func convertFieldsArray(fields graphql.Fields) []*graphql.Field { 6 | covertedFields := []*graphql.Field{} 7 | for key, field := range fields { 8 | field.Name = key 9 | covertedFields = append(covertedFields, field) 10 | } 11 | return covertedFields 12 | } 13 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/model.ts: -------------------------------------------------------------------------------- 1 | import { IPage, IPageCategory } from "model"; 2 | 3 | export interface IAuthComponent { 4 | name: string; 5 | title: string; 6 | } 7 | 8 | export interface IAuthPage { 9 | page: IPage, 10 | components: IAuthComponent[] 11 | } 12 | 13 | export interface IAuthCategory { 14 | category: IPageCategory, 15 | pages: IAuthPage[] 16 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/helper/FileHandlers.ts: -------------------------------------------------------------------------------- 1 | var varfileHandle: any; 2 | 3 | export type FileSystemFileHandle = { 4 | getFile: () => any; 5 | createWritable: () => any; 6 | }; 7 | 8 | export function setHandle(fileHandle: FileSystemFileHandle) { 9 | varfileHandle = fileHandle; 10 | } 11 | 12 | export function getHandle() { 13 | return varfileHandle; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useRelation.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { ID } from "shared"; 3 | import { relationsState } from "../recoil/atoms"; 4 | 5 | export function useRelation(uuid: string, appId: ID) { 6 | const relations = useRecoilValue(relationsState(appId)); 7 | 8 | return relations.find((relation) => relation.uuid === uuid); 9 | } 10 | -------------------------------------------------------------------------------- /studio/src/common/ModelBoard/PropertyBox/ToolbarTitle.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function ToolbarTitle(props: { 4 | children?: any, 5 | }) { 6 | return ( 7 |
12 | {props.children} 13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /studio/src/enthooks/awesome-graphql-client/index.ts: -------------------------------------------------------------------------------- 1 | import { AwesomeGraphQLClient } from './AwesomeGraphQLClient' 2 | import { GraphQLRequestError } from './GraphQLRequestError' 3 | import { gql } from './util/gql' 4 | import { isFileUpload, FileUpload } from './util/isFileUpload' 5 | 6 | export { AwesomeGraphQLClient, GraphQLRequestError, gql, isFileUpload } 7 | export type { FileUpload } 8 | 9 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/ModelAuthBoard/style.less: -------------------------------------------------------------------------------- 1 | .expression-input-modal{ 2 | .input-modal-body{ 3 | flex: 1; 4 | min-height: 300px; 5 | height: calc(100vh - 300px); 6 | .expression-input-area{ 7 | height: 100%; 8 | } 9 | } 10 | .ant-modal-body{ 11 | padding: 0 8px; 12 | } 13 | .script-input-area{ 14 | height: calc(100vh - 340px); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /federation/products/graph/schema.graphqls: -------------------------------------------------------------------------------- 1 | extend type Query { 2 | topProducts(first: Int = 5): [Product] 3 | } 4 | 5 | extend type Subscription { 6 | updatedPrice: Product! 7 | updateProductPrice(upc: String!): Product! 8 | stock: [Product!] 9 | } 10 | 11 | type Product @key(fields: "upc") { 12 | upc: String! 13 | name: String! 14 | price: Int! 15 | inStock: Int! 16 | } -------------------------------------------------------------------------------- /gateway/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch", 6 | "type": "go", 7 | "request": "launch", 8 | "mode": "auto", 9 | "program": "D:/lowcode/leda/gateway/main.go", //调试程序的路径(绝对路径) ${fileDirname} 调试当前文件所在目录下的所有文件 10 | "env": {}, 11 | "args": [] 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /gateway/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.18-buster as builder 2 | 3 | ENV GOPROXY=https://goproxy.cn,direct 4 | ENV GO111MODULE=on 5 | ENV GOFLAGS=-mod=vendor 6 | ENV APP_HOME /go/src/gateway 7 | 8 | WORKDIR "$APP_HOME" 9 | ADD . "$APP_HOME" 10 | 11 | RUN go mod download 12 | RUN go mod verify 13 | RUN go get ./... 14 | RUN go mod vendor 15 | RUN go build -o gateway 16 | 17 | EXPOSE 8081 18 | CMD ["./gateway"] -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./AttributeMeta"; 2 | export * from "./ClassMeta"; 3 | export * from "./CodeMeta"; 4 | export * from "./DiagramMeta"; 5 | export * from "./Meta"; 6 | export * from "./MethodMeta"; 7 | export * from "./PackageMeta"; 8 | export * from "./RelationMeta"; 9 | export * from "./Type"; 10 | export * from "./X6EdgeMeta"; 11 | export * from "./X6NodeMeta"; 12 | -------------------------------------------------------------------------------- /services/models/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.18-buster as builder 2 | 3 | ENV GOPROXY=https://goproxy.cn,direct 4 | ENV GO111MODULE=on 5 | ENV GOFLAGS=-mod=vendor 6 | ENV APP_HOME /go/src/models 7 | 8 | WORKDIR "$APP_HOME" 9 | ADD . "$APP_HOME" 10 | 11 | RUN go mod download 12 | RUN go mod verify 13 | RUN go get ./... 14 | RUN go mod vendor 15 | RUN go build -o models 16 | 17 | EXPOSE 4000 18 | CMD ["./models"] -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/ClassView/ClassNodeData.ts: -------------------------------------------------------------------------------- 1 | import { ClassMeta } from "../../meta/ClassMeta"; 2 | import { X6NodeMeta } from "../../meta/X6NodeMeta"; 3 | 4 | export type ClassNodeData = X6NodeMeta & ClassMeta &{ 5 | packageName?: string; 6 | // selectedId?: string, 7 | //pressedLineType?: RelationType, 8 | //drawingLine:LineAction|undefined, 9 | //themeMode: "dark"|"light" 10 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/useExplorerScrollbarHide.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | 3 | export function useExplorerScrollbarHide(){ 4 | //禁止浏览器滚动,解决x6会增加浏览器滚动条的bug 5 | useEffect(()=>{ 6 | const oldValue = document.body.style.overflow; 7 | document.body.style.overflow = "hidden"; 8 | return ()=>{ 9 | document.body.style.overflow = oldValue; 10 | } 11 | },[]) 12 | } -------------------------------------------------------------------------------- /services/schedule/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.18-buster as builder 2 | 3 | ENV GOPROXY=https://goproxy.cn,direct 4 | ENV GO111MODULE=on 5 | ENV GOFLAGS=-mod=vendor 6 | ENV APP_HOME /go/src/schedule 7 | 8 | WORKDIR "$APP_HOME" 9 | ADD . "$APP_HOME" 10 | 11 | RUN go mod download 12 | RUN go mod verify 13 | RUN go get ./... 14 | RUN go mod vendor 15 | RUN go build -o schedule 16 | 17 | EXPOSE 4000 18 | CMD ["./schedule"] -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useGetProcess.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { ID } from "shared"; 3 | import { useProcesses } from "./useProcesses"; 4 | 5 | export function useGetProcess() { 6 | const processes = useProcesses(); 7 | const getProcess = useCallback((id?: ID) => { 8 | return processes?.find(page => page.id === id) 9 | }, [processes]); 10 | 11 | return getProcess; 12 | } -------------------------------------------------------------------------------- /federation/reviews/graph/schema.graphqls: -------------------------------------------------------------------------------- 1 | type Review { 2 | body: String! 3 | author: User! @provides(fields: "username") 4 | product: Product! 5 | } 6 | 7 | extend type User @key(fields: "id") { 8 | id: ID! @external 9 | username: String! @external 10 | reviews: [Review] 11 | } 12 | 13 | extend type Product @key(fields: "upc") { 14 | upc: String! @external 15 | reviews: [Review] 16 | } 17 | -------------------------------------------------------------------------------- /services/models/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch", 6 | "type": "go", 7 | "request": "launch", 8 | "mode": "auto", 9 | "program": "D:/lowcode/leda/services/models/main.go", //调试程序的路径(绝对路径) ${fileDirname} 调试当前文件所在目录下的所有文件 10 | "env": {}, 11 | "args": [] 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /services/schedule/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Launch", 6 | "type": "go", 7 | "request": "launch", 8 | "mode": "auto", 9 | "program": "D:/lowcode/leda/services/schedule/main.go", //调试程序的路径(绝对路径) ${fileDirname} 调试当前文件所在目录下的所有文件 10 | "env": {}, 11 | "args": [] 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /studio/craco.config.js: -------------------------------------------------------------------------------- 1 | const CracoLessPlugin = require('craco-less'); 2 | 3 | module.exports = { 4 | plugins: [ 5 | { 6 | plugin: CracoLessPlugin, 7 | options: { 8 | lessLoaderOptions: { 9 | lessOptions: { 10 | //modifyVars: { '@primary-color': '#1DA57A' }, 11 | javascriptEnabled: true, 12 | }, 13 | }, 14 | }, 15 | }, 16 | ], 17 | }; -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/ModelAuthBoard/IAuthRow.ts: -------------------------------------------------------------------------------- 1 | import { IClassAuthConfig, IPropertyAuthConfig } from "model"; 2 | 3 | export enum RowType { 4 | Package, 5 | Class, 6 | Property, 7 | } 8 | 9 | export interface IAuthRow { 10 | classUuid?: string; 11 | propertyUuid?: string; 12 | rowType: RowType; 13 | classConfig?: IClassAuthConfig; 14 | propertyConfig?: IPropertyAuthConfig; 15 | } 16 | 17 | 18 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useGetCategoryPages.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { ID } from "shared"; 3 | import { IAuthPage } from "./model"; 4 | 5 | export function useGetCategoryPages(pages: IAuthPage[]) { 6 | const getPages = useCallback((categoryUuid?: ID) => { 7 | return pages?.filter(page => page.page.categoryUuid === categoryUuid) 8 | }, [pages]); 9 | 10 | return getPages 11 | } -------------------------------------------------------------------------------- /studio/src/recoil/atoms.ts: -------------------------------------------------------------------------------- 1 | import { atom } from "recoil"; 2 | import { IApp } from "../model"; 3 | 4 | export const appsState = atom({ 5 | key: "apps", 6 | default: [], 7 | }) 8 | 9 | export const appsLoadingState = atom({ 10 | key: "appsLoading", 11 | default: false, 12 | }) 13 | 14 | export const themeModeState = atom<'light' | 'dark'>({ 15 | key: "themeMode", 16 | default: 'dark', 17 | }) -------------------------------------------------------------------------------- /studio/src/shared/MultLangWidget/index.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react" 2 | import { useParseLangMessage } from "plugin-sdk/hooks/useParseLangMessage"; 3 | 4 | const MultLangWidget = memo(( 5 | props: { 6 | value?: string 7 | } 8 | ) => { 9 | const { value } = props; 10 | const parse = useParseLangMessage(); 11 | return ( 12 | <>{parse(value)} 13 | ) 14 | }) 15 | 16 | export default MultLangWidget; -------------------------------------------------------------------------------- /studio/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /studio/src/common/SvgIcon.tsx: -------------------------------------------------------------------------------- 1 | import Icon from "@ant-design/icons"; 2 | import React from "react"; 3 | 4 | export interface ISvgIconProps { 5 | children: React.ReactElement; 6 | } 7 | 8 | const SvgIcon: React.FC = (props: ISvgIconProps) => { 9 | return ( 10 | 13 | props.children 14 | } 15 | /> 16 | ) 17 | } 18 | 19 | export default SvgIcon -------------------------------------------------------------------------------- /studio/src/datasource/model/EntityMeta.ts: -------------------------------------------------------------------------------- 1 | import { AttributeMeta, MethodMeta } from "designer/AppUml/meta"; 2 | import { AssociationMeta } from "./AssociationMeta"; 3 | 4 | 5 | export interface EntityMeta { 6 | uuid: string; 7 | name: string; 8 | label?: string; 9 | packageUuid: string; 10 | attributes: AttributeMeta[]; 11 | methods: MethodMeta[]; 12 | associations: AssociationMeta[]; 13 | root?: boolean; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/common/CenterSpin/index.tsx: -------------------------------------------------------------------------------- 1 | import { Spin } from "antd" 2 | import React from "react"; 3 | import { memo } from "react" 4 | import "./style.less" 5 | 6 | export const CenterSpin = memo(( 7 | props: { 8 | loading?: boolean, 9 | } 10 | ) => { 11 | const { loading } = props; 12 | return ( 13 |
14 | 15 |
16 | ) 17 | }) -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/IUiAuthConfig.ts: -------------------------------------------------------------------------------- 1 | import { Device } from "@rxdrag/appx-plugin-sdk"; 2 | import { IMenuAuthConfig, IComponentAuthConfig } from "model"; 3 | 4 | export interface IUiAuthRow { 5 | name: string; 6 | label?: string; 7 | refused?: boolean; 8 | menuItemUuid?: string; 9 | componentId?: string; 10 | menuConfig?: IMenuAuthConfig; 11 | device: Device; 12 | componentConfig?: IComponentAuthConfig; 13 | } 14 | -------------------------------------------------------------------------------- /studio/src/common/ModelBoard/ModelToolbar/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from "react"; 2 | import "./style.less"; 3 | 4 | export const ModelToolbar = memo(( 5 | props: { 6 | children?: React.ReactNode, 7 | } 8 | ) => { 9 | const { children } = props; 10 | return ( 11 |
12 |
13 | {children} 14 |
15 |
16 | ); 17 | }); 18 | -------------------------------------------------------------------------------- /studio/src/enthooks/awesome-graphql-client/util/types.ts: -------------------------------------------------------------------------------- 1 | export interface Headers { 2 | get(name: string): string | null 3 | forEach(callbackfn: (value: string, key: string) => void): void 4 | } 5 | 6 | export interface RequestResult { 7 | ok: boolean 8 | headers: Headers 9 | json: () => Promise 10 | status: number 11 | } 12 | 13 | export interface FetchOptions { 14 | method?: string 15 | headers?: any 16 | body?: any 17 | } 18 | -------------------------------------------------------------------------------- /services/models/errorx/error.go: -------------------------------------------------------------------------------- 1 | package errorx 2 | 3 | import ( 4 | "encoding/json" 5 | ) 6 | 7 | type Error struct { 8 | Code string `json:"code"` 9 | Message string `json:"message"` 10 | } 11 | 12 | func New(code, message string) Error { 13 | return Error{ 14 | Code: code, 15 | Message: message, 16 | } 17 | } 18 | 19 | func (e Error) Error() string { 20 | jsonByte, _ := json.Marshal(e) 21 | return string(jsonByte) 22 | } 23 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/constLabelPosition.ts: -------------------------------------------------------------------------------- 1 | export const ROLE_SOURCE_POSITION_CONST = { 2 | distance: 40, 3 | offset: 20, 4 | } 5 | 6 | export const MULTI_SOURCE_POSITION_CONST = { 7 | distance: 40, 8 | offset: -20, 9 | } 10 | 11 | export const ROLE_SOURCE_TARGET_CONST = { 12 | distance: -40, 13 | offset: 20, 14 | } 15 | 16 | export const MULTI_SOURCE_TARGET_CONST = { 17 | distance: -40, 18 | offset: -20, 19 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/PropertyPanel/ScriptInput/style.less: -------------------------------------------------------------------------------- 1 | .script-input-modal{ 2 | .input-modal-body{ 3 | flex: 1; 4 | min-height: 300px; 5 | height: calc(100vh - 300px); 6 | .script-input-area{ 7 | height: 100%; 8 | } 9 | } 10 | .ant-modal-body{ 11 | padding: 0 8px; 12 | } 13 | .footer-toolbar{ 14 | width: 100%; 15 | display: flex; 16 | justify-content: space-between; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useRole.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { authRolesState } from "../recoil/atoms"; 5 | 6 | export function useRole(roleId?: ID) { 7 | const roles = useRecoilValue(authRolesState); 8 | 9 | const role = useMemo(() => { 10 | return roles?.find(role => role.id === roleId) 11 | }, [roles, roleId]) 12 | 13 | return role; 14 | } -------------------------------------------------------------------------------- /services/schedule/README.md: -------------------------------------------------------------------------------- 1 | 定时任务 2 | 3 | 任务可以分为一次性任务跟周期执行任务 4 | 5 | 每个服务用的实体需要单独定义 6 | 7 | 接口定义 8 | 9 | type Task struct { 10 | id int 11 | name string 12 | config json 13 | api string 14 | type string //post, graphql muation 15 | } 16 | 17 | tasks():Task[] 18 | createTask(task: Task, start: bool) 19 | 20 | start(taskId: string) 21 | end(taskId: string) 22 | 23 | 创建镜像: 24 | docker build --pull --rm -f "Dockerfile" -t idlewater2/schedule:v0.0.2 "." -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useSelectedCode.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { ID } from "shared"; 3 | import { codesState, selectedElementState } from "../recoil/atoms"; 4 | 5 | export function useSelectedCode(appId: ID) { 6 | const selectedElementId = useRecoilValue(selectedElementState(appId)); 7 | const codes = useRecoilValue(codesState(appId)); 8 | 9 | return codes.find((code) => code.uuid === selectedElementId); 10 | } 11 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useParsePageComponents.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { IPage } from "model"; 3 | import { IAuthComponent } from "./model"; 4 | import { useParseSchema } from "./useParseSchema"; 5 | 6 | export function useParsePageComponents() { 7 | const p = useParseSchema(); 8 | const parse = useCallback((page: IPage): IAuthComponent[] => { 9 | return p(page.schemaJson?.schema); 10 | }, [p]) 11 | 12 | return parse; 13 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useGetCategoryProcesses.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { ID } from "shared"; 3 | import { useProcesses } from "./useProcesses"; 4 | 5 | export function useGetCategoryProcesses() { 6 | const processes = useProcesses(); 7 | const getProcesses = useCallback((categoryUuid?: ID) => { 8 | return processes?.filter(process => process.categoryUuid === categoryUuid) 9 | }, [processes]); 10 | 11 | return getProcesses 12 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useIsCode.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { useRecoilValue } from 'recoil'; 3 | import { codesState } from "../recoil/atoms"; 4 | import { useCallback } from 'react'; 5 | 6 | export function useIsCode(appId: ID) { 7 | const codes = useRecoilValue(codesState(appId)) 8 | 9 | const isCode = useCallback((uuid?: string) => { 10 | return !!codes.find(code => code.uuid === uuid) 11 | }, [codes]) 12 | 13 | return isCode 14 | } -------------------------------------------------------------------------------- /studio/src/model/lang.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { IApp, IAppInput } from "./app"; 3 | 4 | export interface ILang { 5 | key: string, 6 | abbr: string, 7 | } 8 | 9 | export interface ILangLocal { 10 | id: ID; 11 | name: string; 12 | app?: IApp; 13 | schemaJson?: any; 14 | } 15 | 16 | export interface ILangLocalInput { 17 | id?: ID; 18 | name?: string; 19 | app?: { 20 | sync: IAppInput 21 | }; 22 | schemaJson?: any; 23 | } 24 | 25 | -------------------------------------------------------------------------------- /studio/src/common/ModelBoard/PropertyBox/ToolbarArea.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default function ToolbarArea(props: { 4 | children?: any 5 | }) { 6 | return ( 7 |
14 | {props.children} 15 |
16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /studio/src/model/menu.ts: -------------------------------------------------------------------------------- 1 | import { Device } from "@rxdrag/appx-plugin-sdk"; 2 | import { IMenuItem } from "plugin-sdk"; 3 | import { ID } from "shared"; 4 | import { IApp, IAppInput } from "./app"; 5 | 6 | export interface IMenu { 7 | id: ID; 8 | schemaJson: { items: IMenuItem[] }; 9 | device: Device; 10 | app: IApp; 11 | } 12 | 13 | export interface IMenuInput { 14 | id?: ID; 15 | device?: Device; 16 | schemaJson?: any; 17 | app?: { sync: IAppInput }; 18 | } 19 | -------------------------------------------------------------------------------- /studio/src/model/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./app" 2 | export * from "./auth" 3 | export * from "./file" 4 | export * from "./lang" 5 | export * from "./log" 6 | export * from "./material" 7 | export * from "./menu" 8 | export * from "./notification" 9 | export * from "./page" 10 | export * from "./template" 11 | export * from "./uiframe" 12 | export * from "./plugin" 13 | export * from "./process" 14 | export * from "./role" 15 | export * from "./app" 16 | export * from "./snapshot" 17 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/RoleList/style.less: -------------------------------------------------------------------------------- 1 | .role-list{ 2 | flex: 1; 3 | display: flex; 4 | flex-flow: column; 5 | height: 0; 6 | .roles-title{ 7 | padding: 8px 24px; 8 | height: 40px; 9 | //font-weight: 600; 10 | display: flex; 11 | align-items: center; 12 | } 13 | .role-list-body{ 14 | flex: 1; 15 | display: flex; 16 | flex-flow: column; 17 | overflow: auto; 18 | .ant-menu-inline{ 19 | border-right: 0, 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useIsDiagram.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { useRecoilValue } from 'recoil'; 3 | import { diagramsState } from "../recoil/atoms"; 4 | import { useCallback } from 'react'; 5 | 6 | export function useIsDiagram(appId: ID) { 7 | const diagrams = useRecoilValue(diagramsState(appId)) 8 | 9 | const isDiagram = useCallback((uuid: string) => { 10 | return diagrams.find(d => d.uuid === uuid) 11 | }, [diagrams]) 12 | 13 | return isDiagram 14 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useSelectedRelation.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { ID } from "shared"; 3 | import { relationsState, selectedElementState } from "../recoil/atoms"; 4 | 5 | export function useSelectedRelation(appId: ID) { 6 | const selectedElement = useRecoilValue(selectedElementState(appId)); 7 | const relations = useRecoilValue(relationsState(appId)); 8 | 9 | return relations.find((relation) => relation.uuid === selectedElement); 10 | } 11 | -------------------------------------------------------------------------------- /services/schedule/resolver/mutation.go: -------------------------------------------------------------------------------- 1 | package resolver 2 | 3 | import ( 4 | "context" 5 | ) 6 | 7 | func (*Resolver) HelloMutation(id ID, ctx context.Context) ID { 8 | //runner.TaskRunner.StartTask() 9 | return "HelloMutation !" 10 | } 11 | 12 | // func (*Resolver) StopTask(id ID, ctx context.Context) ID { 13 | // numId, err := strconv.ParseInt(id, 10, 64) 14 | // if err == nil { 15 | // runner.TaskRunner.StopTask(numId) 16 | // } 17 | 18 | // return "cancelOneShotTask !" 19 | // } 20 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetClass.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { classesState } from "../recoil/atoms"; 5 | 6 | export function useGetClass(appId: ID) { 7 | const classes = useRecoilValue(classesState(appId)); 8 | 9 | const getEntity = useCallback((uuid: string)=>{ 10 | return classes.find((cls) => cls.uuid === uuid); 11 | }, [classes]); 12 | 13 | return getEntity; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/model/material.ts: -------------------------------------------------------------------------------- 1 | import { Device, IMaterialTab } from "@rxdrag/appx-plugin-sdk"; 2 | import { ID } from "shared"; 3 | import { IApp, IAppInput } from "./app"; 4 | 5 | export interface IMaterialConfigInput { 6 | id?: ID; 7 | device?: Device, 8 | app?: { sync?: IAppInput } 9 | schemaJson?: { 10 | tabs: IMaterialTab[], 11 | }, 12 | } 13 | 14 | export interface IMaterialConfig { 15 | id: ID; 16 | app?: IApp; 17 | schemaJson?: { 18 | tabs: IMaterialTab[], 19 | }, 20 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/DiagramMeta.ts: -------------------------------------------------------------------------------- 1 | import { X6EdgeMeta } from "./X6EdgeMeta"; 2 | import { X6NodeMeta } from "./X6NodeMeta"; 3 | 4 | /** 5 | * ER图元数据 6 | */ 7 | export interface DiagramMeta { 8 | /** 9 | * 唯一标识 10 | */ 11 | uuid: string; 12 | 13 | /** 14 | * ER图名称 15 | */ 16 | name: string; 17 | 18 | packageUuid: string; 19 | 20 | /** 21 | * 节点 22 | */ 23 | nodes: X6NodeMeta[]; 24 | 25 | /** 26 | * 关系的连线 27 | */ 28 | edges: X6EdgeMeta[]; 29 | } 30 | -------------------------------------------------------------------------------- /services/models/modules/app/middleware.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "context" 5 | "net/http" 6 | 7 | "codebdy.com/leda/services/models/consts" 8 | "github.com/codebdy/entify-graphql-schema/resolve" 9 | ) 10 | 11 | func LoadersMiddleware(next http.Handler) http.Handler { 12 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 13 | ctx := context.WithValue(r.Context(), consts.LOADERS, resolve.CreateDataLoaders()) 14 | next.ServeHTTP(w, r.WithContext(ctx)) 15 | }) 16 | } 17 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetCodeByName.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { codesState } from "../recoil/atoms"; 5 | 6 | export function useGetCodeByName(appId: ID) { 7 | const codes = useRecoilValue(codesState(appId)); 8 | 9 | const getCodeByName = useCallback((name: string) => { 10 | return codes.find((code) => code.name === name); 11 | }, [codes]); 12 | 13 | return getCodeByName; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetPackage.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { packagesState } from './../recoil/atoms'; 5 | 6 | export function useGetPackage(appId: ID) { 7 | const packages = useRecoilValue(packagesState(appId)); 8 | 9 | const getEntity = useCallback((uuid: string)=>{ 10 | return packages.find((pkg) => pkg.uuid === uuid); 11 | }, [packages]); 12 | 13 | return getEntity; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/enthooks/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./useLogin" 2 | export * from "./useLogout" 3 | export * from "./IQueryInput" 4 | export * from "./useChangePassword" 5 | export * from "./useDeleteById" 6 | export * from "./useDeleteByIds" 7 | export * from "./useInstall" 8 | export * from "./useLazyRequest" 9 | export * from "./useMountRef" 10 | export * from "./usePost" 11 | export * from "./usePostOne" 12 | export * from "./useQuery" 13 | export * from "./useQueryMe" 14 | export * from "./useQueryOne" 15 | -------------------------------------------------------------------------------- /federation/products/graph/products.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import "github.com/wundergraph/graphql-go-tools/examples/federation/products/graph/model" 4 | 5 | var hats = []*model.Product{ 6 | { 7 | Upc: "top-1", 8 | Name: "Trilby", 9 | Price: 11, 10 | InStock: 500, 11 | }, 12 | { 13 | Upc: "top-2", 14 | Name: "Fedora", 15 | Price: 22, 16 | InStock: 1200, 17 | }, 18 | { 19 | Upc: "top-3", 20 | Name: "Boater", 21 | Price: 33, 22 | InStock: 850, 23 | }, 24 | } 25 | -------------------------------------------------------------------------------- /studio/src/designer/ApiBoard/index.less: -------------------------------------------------------------------------------- 1 | .api-board{ 2 | //flex: 1; 3 | //display: flex; 4 | width: 100vw; 5 | height: calc(100vh - 64px); 6 | overflow: hidden; 7 | .graphiql-container { 8 | .docExplorerResizer{ 9 | height: auto; 10 | } 11 | .doc-explorer-title-bar { 12 | display: flex; 13 | } 14 | .doc-explorer-title-bar { 15 | padding: 0; 16 | } 17 | .doc-explorer-contents { 18 | top: 34px; 19 | padding-top: 10px; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /studio/src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from 'web-vitals'; 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry); 7 | getFID(onPerfEntry); 8 | getFCP(onPerfEntry); 9 | getLCP(onPerfEntry); 10 | getTTFB(onPerfEntry); 11 | }); 12 | } 13 | }; 14 | 15 | export default reportWebVitals; 16 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetClassByName.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { classesState } from "../recoil/atoms"; 5 | 6 | export function useGetClassByName(appId: ID) { 7 | const entites = useRecoilValue(classesState(appId)); 8 | 9 | const getClassByName = useCallback((name: string) => { 10 | return entites.find((ent) => ent.name === name); 11 | }, [entites]); 12 | 13 | return getClassByName; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useSelectedOrcherstration.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { ID } from "shared"; 3 | import { orchestrationsState, selectedElementState } from "../recoil/atoms"; 4 | 5 | export function useSelectedOrcherstration(appId: ID) { 6 | const selectedElementId = useRecoilValue(selectedElementState(appId)); 7 | const orchestrations = useRecoilValue(orchestrationsState(appId)); 8 | 9 | return orchestrations.find((orches) => orches.uuid === selectedElementId); 10 | } 11 | -------------------------------------------------------------------------------- /gateway/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/nautilus/gateway/cmd/gateway/server" 5 | "github.com/spf13/cobra" 6 | ) 7 | 8 | var rootCmd = &cobra.Command{ 9 | Use: "graphql-gateway", 10 | Short: "GraphQL Gateway is a standalone service to consolidate your GraphQL APIs.", 11 | } 12 | 13 | // start the gateway executable 14 | func main() { 15 | server.Services = []string{ 16 | "http://models:4000/graphql", 17 | "http://schedule:4002/graphql", 18 | } 19 | server.ListenAndServe("8081") 20 | } 21 | -------------------------------------------------------------------------------- /services/models/contexts/contexts.go: -------------------------------------------------------------------------------- 1 | package contexts 2 | 3 | import ( 4 | "context" 5 | 6 | "codebdy.com/leda/services/models/consts" 7 | ) 8 | 9 | type ContextValues struct { 10 | Token string 11 | AppId uint64 12 | AppName string 13 | Host string 14 | IP string 15 | } 16 | 17 | func Values(ctx context.Context) ContextValues { 18 | values := ctx.Value(consts.CONTEXT_VALUES) 19 | if values == nil { 20 | panic("Not set CONTEXT_VALUES in context") 21 | } 22 | return values.(ContextValues) 23 | } 24 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/useDnd.ts: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from "react"; 2 | import { Dnd } from "@antv/x6-plugin-dnd"; 3 | import { Graph } from "@antv/x6"; 4 | 5 | 6 | export function useDnd(graph: Graph|undefined) { 7 | const [dnd, setDnd] = React.useState() 8 | useEffect(() => { 9 | const theDnd = graph 10 | ? new Dnd({ 11 | target: graph, 12 | scaled: false, 13 | }) 14 | : undefined; 15 | setDnd(theDnd); 16 | }, [graph]); 17 | 18 | return dnd 19 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useClassPackage.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ClassMeta } from "../meta/ClassMeta"; 4 | import { packagesState } from "../recoil/atoms"; 5 | 6 | export function useClassPackage(appId: string){ 7 | const packages = useRecoilValue(packagesState(appId)) 8 | const getPackage = useCallback((cls: ClassMeta)=>{ 9 | return packages.find(pkg=>pkg.uuid === cls.packageUuid) 10 | }, [packages]) 11 | 12 | return getPackage 13 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useDiagramNodes.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { x6NodesState } from "../recoil/atoms"; 5 | 6 | export function useDiagramNodes(diagramUuid:string, appId: ID){ 7 | const nodes = useRecoilValue(x6NodesState(appId)); 8 | 9 | const diagramNodes = useMemo(()=>{ 10 | return nodes.filter(node=>node.diagramUuid === diagramUuid) 11 | }, [diagramUuid, nodes]) 12 | 13 | return diagramNodes; 14 | } -------------------------------------------------------------------------------- /gateway/middlewares/appheader.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import ( 4 | "net/http" 5 | 6 | ledaconsts "github.com/codebdy/leda-service-sdk/consts" 7 | "github.com/nautilus/graphql" 8 | ) 9 | 10 | func AppHeader(header http.Header) graphql.NetworkMiddleware { 11 | return func(r *http.Request) error { 12 | r.Header.Set(ledaconsts.HEADER_LEDA_APPNAME, header.Get(ledaconsts.HEADER_LEDA_APPNAME)) 13 | r.Header.Set(ledaconsts.HEADER_LEDA_APPID, header.Get(ledaconsts.HEADER_LEDA_APPID)) 14 | return nil 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetPackageByName.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { packagesState } from './../recoil/atoms'; 5 | 6 | export function useGetPackageByName(appId: ID) { 7 | const packages = useRecoilValue(packagesState(appId)); 8 | const getPackageByName = useCallback((name: string) => { 9 | return packages.find((pkg) => pkg.name === name); 10 | }, [packages]); 11 | 12 | return getPackageByName; 13 | } 14 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetRelation.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { relationsState } from "../recoil/atoms"; 5 | 6 | export function useGetRelation(appId: ID) { 7 | const relations = useRecoilValue(relationsState(appId)); 8 | 9 | const getRelation = useCallback((uuid: string) => { 10 | return relations.find((relation) => relation.uuid === uuid); 11 | }, [relations]); 12 | 13 | return getRelation; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/designer/hooks/useLoginCheck.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import { useNavigate } from "react-router-dom"; 3 | import { LOGIN_URL } from "../../consts"; 4 | import { useEntix, useToken } from "../../enthooks"; 5 | 6 | export function useLoginCheck() { 7 | const navigate = useNavigate(); 8 | const entix = useEntix(); 9 | const token = useToken() 10 | 11 | useEffect(() => { 12 | if (entix?.tokenName && !token) { 13 | navigate(LOGIN_URL); 14 | } 15 | }, [entix, token, navigate]) 16 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/ProcessList/index.less: -------------------------------------------------------------------------------- 1 | // .ant-formily-layout{ 2 | // form{ 3 | // height: 100%; 4 | // } 5 | // } 6 | 7 | .process-list-shell{ 8 | display: flex; 9 | flex:1; 10 | height: 100%; 11 | flex-flow: column; 12 | padding: 16px; 13 | .process-list-action{ 14 | padding: 0 0px; 15 | display: flex; 16 | justify-content: space-evenly; 17 | width: 100%; 18 | } 19 | 20 | .process-list-tree{ 21 | flex: 1; 22 | overflow: auto; 23 | margin-top: 16px; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useEnums.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { StereoType } from "../meta/ClassMeta"; 5 | import { classesState } from "../recoil/atoms"; 6 | 7 | export function useEnums(appId: ID) { 8 | const entities = useRecoilValue(classesState(appId)); 9 | const enums = useMemo(() => { 10 | return entities.filter((entity) => entity.stereoType === StereoType.Enum); 11 | }, [entities]); 12 | 13 | return enums; 14 | } 15 | -------------------------------------------------------------------------------- /services/schedule/runner/job.go: -------------------------------------------------------------------------------- 1 | package runner 2 | 3 | import ( 4 | "codebdy.com/leda/services/schedule/entities" 5 | ) 6 | 7 | type Job struct { 8 | task *entities.Task 9 | } 10 | 11 | func (j Job) Run() { 12 | if j.task.Config.RequestType == entities.REQUEST_TYPE_GRAPHQL { 13 | excuteGraphqlTask(*j.task) 14 | } else if j.task.Config.RequestType == entities.REQUEST_TYPE_HTTP_GET { 15 | panic("Not implement") 16 | } else if j.task.Config.RequestType == entities.REQUEST_TYPE_HTTP_POST { 17 | panic("Not implement") 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useEntities.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { StereoType } from "../meta/ClassMeta"; 5 | import { classesState } from "../recoil/atoms"; 6 | 7 | export function useEntities(appId: ID) { 8 | const classes = useRecoilValue(classesState(appId)); 9 | const entities = useMemo(() => { 10 | return classes.filter((cls) => cls.stereoType === StereoType.Entity); 11 | }, [classes]); 12 | 13 | return entities; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetDiagramByName.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { diagramsState } from "../recoil/atoms"; 5 | 6 | export function useGetDiagramByName(appId: ID) { 7 | const diagrams = useRecoilValue(diagramsState(appId)); 8 | 9 | const getDiagramByName = useCallback((name: string) => { 10 | return diagrams.find((diagram) => diagram.name === name); 11 | }, [diagrams]); 12 | 13 | return getDiagramByName; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/model/uiframe.ts: -------------------------------------------------------------------------------- 1 | import { Device } from "@rxdrag/appx-plugin-sdk"; 2 | import { ID } from "shared"; 3 | import { IApp, IAppInput } from "./app"; 4 | 5 | export interface IUiFrame { 6 | id: ID; 7 | title: string; 8 | uuid: string; 9 | schemaJson: { form: any, schema: any/*ISchema*/ }; 10 | device: Device; 11 | app?: IApp; 12 | } 13 | 14 | export interface IUiFrameInput { 15 | id?: ID; 16 | title?: string; 17 | uuid?: string; 18 | schemaJson?: any; 19 | device?: Device; 20 | app?: { sync: IAppInput }; 21 | } 22 | -------------------------------------------------------------------------------- /studio/src/dashboard/StyledThemeRoot.tsx: -------------------------------------------------------------------------------- 1 | import { useToken } from "antd/es/theme/internal"; 2 | import { memo, useMemo } from "react" 3 | import { ThemeProvider } from "styled-components"; 4 | 5 | export const StyledThemeRoot = memo((props: { 6 | children: React.ReactNode 7 | }) => { 8 | const { children } = props; 9 | const [, token] = useToken() 10 | const theme = useMemo(() => { 11 | return { 12 | token 13 | } 14 | }, [token]) 15 | return ( 16 | {children} 17 | ) 18 | }) -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useIsOrchestration.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { useRecoilValue } from 'recoil'; 3 | import { orchestrationsState } from "../recoil/atoms"; 4 | import { useCallback } from 'react'; 5 | 6 | export function useIsOrchestration(appId: ID) { 7 | const orchestrations = useRecoilValue(orchestrationsState(appId)) 8 | const isOrchestration = useCallback((uuid?: string) => { 9 | return !!orchestrations.find(orches => orches.uuid === uuid) 10 | }, [orchestrations]) 11 | 12 | return isOrchestration 13 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useSelectedDiagramPackageUuid.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { useRecoilValue } from 'recoil'; 3 | import { diagramsState } from "../recoil/atoms"; 4 | import { selectedUmlDiagramState } from '../recoil/atoms'; 5 | 6 | export function useSelectedDiagramPackageUuid(appId: ID) { 7 | const diagrams = useRecoilValue(diagramsState(appId)); 8 | const selectedDiagramId = useRecoilValue(selectedUmlDiagramState(appId)); 9 | return diagrams.find(diagram => diagram.uuid === selectedDiagramId)?.packageUuid; 10 | } -------------------------------------------------------------------------------- /federation/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | function cleanup { 4 | kill "$ACCOUNTS_PID" 5 | kill "$PRODUCTS_PID" 6 | kill "$REVIEWS_PID" 7 | } 8 | trap cleanup EXIT 9 | 10 | go build -o /tmp/srv-accounts ./accounts 11 | go build -o /tmp/srv-products ./products 12 | go build -o /tmp/srv-reviews ./reviews 13 | go build -o /tmp/srv-gateway ./gateway 14 | 15 | /tmp/srv-accounts & 16 | ACCOUNTS_PID=$! 17 | 18 | /tmp/srv-products & 19 | PRODUCTS_PID=$! 20 | 21 | /tmp/srv-reviews & 22 | REVIEWS_PID=$! 23 | 24 | sleep 1 25 | 26 | /tmp/srv-gateway 27 | -------------------------------------------------------------------------------- /studio/src/plugin-sdk/locales/commonLocales.ts: -------------------------------------------------------------------------------- 1 | import { styleLocales } from "./styleLocales"; 2 | 3 | export const commonLocales = { 4 | 'zh-CN': { 5 | props: { 6 | cursor: "光标", 7 | onClick: '鼠标点击', 8 | 'component-tab':"组件", 9 | 'component-group': '组件属性', 10 | 'component-style-group': '组件样式', 11 | style: styleLocales['zh-CN'] 12 | }, 13 | }, 14 | 'en-US': { 15 | props: { 16 | cursor: "Cursor", 17 | onClick: "on Click", 18 | style: styleLocales['en-US'] 19 | }, 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /services/models/logs/consts.go: -------------------------------------------------------------------------------- 1 | package logs 2 | 3 | const ( 4 | SUCCESS = "success" 5 | FAILURE = "failure" 6 | QUERY = "query" 7 | UPSERT = "upsert" 8 | MULTI_UPSERT = "multiUpsert" 9 | SET = "set" 10 | DELETE = "delete" 11 | MULTI_DELETE = "multiDelete" 12 | 13 | INSTALL = "install" 14 | LOGIN = "login" 15 | LOGOUT = "logout" 16 | DEPLOYP_ROCESS = "deployProcess" 17 | STARTP_ROCESS = "startProcess" 18 | COMPLATE_JOB = "complateJob" 19 | PUBLISH_META = "publishMeta" 20 | ) 21 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useValueObjects.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { StereoType } from "../meta/ClassMeta"; 5 | import { classesState } from "../recoil/atoms"; 6 | 7 | export function useValueObjects(appId: ID) { 8 | const classes = useRecoilValue(classesState(appId)); 9 | const valueObjs = useMemo(() => { 10 | return classes.filter((cls) => cls.stereoType === StereoType.ValueObject); 11 | }, [classes]); 12 | 13 | return valueObjs; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/model/user.ts: -------------------------------------------------------------------------------- 1 | import { IUser } from "enthooks"; 2 | import { ID } from "shared"; 3 | import { IApp, IAppInput } from "./app"; 4 | 5 | export interface IUserInput { 6 | id?: ID; 7 | } 8 | 9 | export interface IUserConfig { 10 | id: ID; 11 | app?: IApp, 12 | user?: IUser; 13 | schemaJson?: { 14 | [path: string]: any, 15 | }, 16 | } 17 | 18 | export interface IUserConfigInput { 19 | id?: ID; 20 | app?: { sync: IAppInput }; 21 | user?: { sync: IUserInput }; 22 | schemaJson?: { 23 | [path: string]: any, 24 | }, 25 | } 26 | 27 | -------------------------------------------------------------------------------- /studio/src/designer/AppDesignBoard/inex.tsx: -------------------------------------------------------------------------------- 1 | 2 | import { Layout } from 'antd'; 3 | import React, { memo } from 'react'; 4 | import { Outlet } from 'react-router-dom'; 5 | import { useDesignerParams } from 'plugin-sdk'; 6 | import DesignerHeader from "../DesignerHeader"; 7 | 8 | const { Content } = Layout; 9 | export const AppDesignBoard = memo(() => { 10 | const { app } = useDesignerParams(); 11 | return ( 12 | 13 | 14 | 15 | 16 | 17 | 18 | ) 19 | }) -------------------------------------------------------------------------------- /studio/src/designer/ThemeRoot/index.tsx: -------------------------------------------------------------------------------- 1 | import { useToken } from "antd/es/theme/internal" 2 | import React, { memo, useMemo } from "react" 3 | 4 | import { ThemeProvider } from "styled-components" 5 | 6 | export const ThemeRoot = memo(( 7 | props: { 8 | children?: React.ReactNode 9 | } 10 | ) => { 11 | const [, token] = useToken() 12 | const theme = useMemo(() => { 13 | return { 14 | token 15 | } 16 | }, [token]) 17 | 18 | return ( 19 | 20 | {props.children} 21 | 22 | ) 23 | }) -------------------------------------------------------------------------------- /studio/src/datasource/hooks/useGetEntity.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { useSelectedAppId } from "plugin-sdk/contexts/desinger"; 4 | import { entitiesState } from "../recoil"; 5 | 6 | export function useGetEntity() { 7 | const appId = useSelectedAppId(); 8 | const entities = useRecoilValue(entitiesState(appId)) 9 | 10 | const getEntity = useCallback((enitityUuid?: string) => { 11 | return entities.find(entity => entity.uuid === enitityUuid); 12 | }, [entities]) 13 | 14 | return getEntity 15 | } -------------------------------------------------------------------------------- /services/schedule/entities/Task.go: -------------------------------------------------------------------------------- 1 | package entities 2 | 3 | import "time" 4 | 5 | const TASK_NAME = "Task" 6 | 7 | type Task struct { 8 | Id int64 `json:"id"` 9 | Name string `json:"name"` 10 | CronExpression string `json:"cronExpression"` 11 | Status string `json:"status"` 12 | CreatedAt time.Time `json:"createdAt"` 13 | UpdatedAt time.Time `json:"updatedAt"` 14 | Config TaskConfig `json:"config"` 15 | RunAt time.Time `json:"runAt"` 16 | StopedAt time.Time `json:"stopedAt"` 17 | } 18 | -------------------------------------------------------------------------------- /studio/src/common/ModelBoard/ModelToolbar/style.less: -------------------------------------------------------------------------------- 1 | @import "../../../variables.less"; 2 | 3 | .model-toolbar{ 4 | display: flex; 5 | width: 100%; 6 | height: 48px; 7 | background-color: @backgrounColor; 8 | align-items: center; 9 | border-bottom: solid 1px @borderColor; 10 | .toolbarInner { 11 | flex: 1; 12 | display: flex; 13 | height: 100%; 14 | margin-right: 16px; 15 | margin-left: 16px; 16 | align-items: center; 17 | }; 18 | .saveButtonShell { 19 | display: flex; 20 | align-items: center; 21 | margin-left: 32px; 22 | }; 23 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/items/NameItem.tsx: -------------------------------------------------------------------------------- 1 | import { Form, Input } from "antd"; 2 | import React from "react"; 3 | import { useTranslation } from "react-i18next"; 4 | //import { MultiLangInput } from "plugins/inputs/components/pc/MultiLangInput/view"; 5 | 6 | export const NameItem = () => { 7 | const { t } = useTranslation() 8 | return ( 9 | 13 | {/* */} 14 | 15 | 16 | ) 17 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/PropertyPanel/MethodPanel/ArgsInput/style.less: -------------------------------------------------------------------------------- 1 | .args-input-modal{ 2 | .args-input-body{ 3 | flex: 1; 4 | min-height: 300px; 5 | height: calc(100vh - 400px); 6 | display: flex; 7 | flex-flow: column; 8 | overflow: auto; 9 | .arg-item{ 10 | display: flex; 11 | } 12 | } 13 | } 14 | 15 | .row-dragging { 16 | background: #fafafa; 17 | border: 1px solid #ccc; 18 | z-index: 1000; 19 | } 20 | 21 | .row-dragging td { 22 | padding: 16px; 23 | } 24 | 25 | .row-dragging .drag-visible { 26 | visibility: visible; 27 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useDeleteProcess.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { IDeleteOptions, useDeleteById } from "enthooks/hooks/useDeleteById"; 3 | import { IProcess } from "model/process"; 4 | 5 | export function useDeleteProcess(options?: IDeleteOptions): [ 6 | (id: ID) => void, 7 | { 8 | error?: Error, 9 | loading?: boolean, 10 | } 11 | ] { 12 | const [doDelete, { error, loading }] = useDeleteById("Process", 13 | { 14 | ...options 15 | } 16 | ); 17 | 18 | return [doDelete, { error: error, loading: loading }] 19 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/plugins/palette/CustomPaletteProvider.ts: -------------------------------------------------------------------------------- 1 | export default class CustomPaletteProvider { 2 | constructor(palette: any) { 3 | palette.registerProvider(this); 4 | } 5 | 6 | getPaletteEntries() { 7 | return function (entries: any) { 8 | //delete entries["create.exclusive-gateway"]; 9 | //delete entries["create.intermediate-event"]; 10 | delete entries["create.data-object"]; 11 | delete entries["create.data-store"]; 12 | return entries; 13 | }; 14 | } 15 | } 16 | 17 | (CustomPaletteProvider as any).$inject = ["palette"]; 18 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetEdge.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { x6EdgesState } from "../recoil/atoms"; 5 | 6 | export function useGetEdge(appId: ID) { 7 | const edges = useRecoilValue(x6EdgesState(appId)); 8 | const getEdge = useCallback( 9 | (id: string, diagramUuid: string) => { 10 | return edges.find( 11 | (edage) => edage.id === id && edage.diagramUuid === diagramUuid 12 | ); 13 | }, 14 | [edges] 15 | ); 16 | 17 | return getEdge; 18 | } 19 | -------------------------------------------------------------------------------- /studio/src/datasource/recoil/index.ts: -------------------------------------------------------------------------------- 1 | import { atomFamily } from "recoil"; 2 | import { PackageMeta, ClassMeta } from "designer/AppUml/meta"; 3 | 4 | import { EntityMeta } from "../model/EntityMeta"; 5 | 6 | export const packagesState = atomFamily({ 7 | key: "designer.packages", 8 | default: [], 9 | }) 10 | 11 | export const classesState = atomFamily({ 12 | key: "designer.classes", 13 | default: [], 14 | }) 15 | 16 | export const entitiesState = atomFamily({ 17 | key: "designer.entities", 18 | default: [], 19 | }) 20 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetNode.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { x6NodesState } from "../recoil/atoms"; 5 | 6 | export function useGetNode(appId: ID) { 7 | const nodes = useRecoilValue(x6NodesState(appId)); 8 | 9 | const getNode = useCallback( 10 | (uuid: string, diagramUuid: string) => { 11 | return nodes.find( 12 | (node) => node.id === uuid && node.diagramUuid === diagramUuid 13 | ); 14 | }, 15 | [nodes] 16 | ); 17 | 18 | return getNode; 19 | } 20 | -------------------------------------------------------------------------------- /studio/src/designer/hooks/useDeleteLangLocal.ts: -------------------------------------------------------------------------------- 1 | import { IDeleteOptions, useDeleteById } from "../../enthooks/hooks/useDeleteById"; 2 | import { ILangLocal } from "../../model"; 3 | import { ID } from "shared"; 4 | 5 | 6 | export function useDeleteLangLocal(options?: IDeleteOptions): [ 7 | (id: ID) => void, 8 | { 9 | error?: Error, 10 | loading?: boolean, 11 | } 12 | ] { 13 | const [doDelete, { error, loading }] = useDeleteById("LangLocal", 14 | { 15 | ...options 16 | } 17 | ); 18 | 19 | return [doDelete, { error: error, loading: loading }] 20 | } -------------------------------------------------------------------------------- /studio/src/shared/formatFileSize.ts: -------------------------------------------------------------------------------- 1 | export function formatFileSize(fileSize: number) { 2 | if (fileSize < 1024) { 3 | return fileSize + ' bytes'; 4 | } else if (fileSize < (1024 * 1024)) { 5 | var temp: any = fileSize / 1024; 6 | temp = temp.toFixed(2); 7 | return temp + 'KB'; 8 | } else if (fileSize < (1024 * 1024 * 1024)) { 9 | var temp: any = fileSize / (1024 * 1024); 10 | temp = temp.toFixed(2); 11 | return temp + 'MB'; 12 | } else { 13 | var temp: any = fileSize / (1024 * 1024 * 1024); 14 | temp = temp.toFixed(2); 15 | return temp + 'GB'; 16 | } 17 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetOrchestrationByName.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { orchestrationsState } from "../recoil/atoms"; 5 | 6 | export function useGetOrchestrationByName(appId: ID) { 7 | const orchestrations = useRecoilValue(orchestrationsState(appId)); 8 | 9 | const getOrchestrationByName = useCallback((name: string) => { 10 | return orchestrations.find((orchestration) => orchestration.name === name); 11 | }, [orchestrations]); 12 | 13 | return getOrchestrationByName; 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useCustomTranslate.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | 4 | export function useCustomTranslate() { 5 | const { t } = useTranslation(); 6 | 7 | const translate = useCallback((template: any, replacements: any) => { 8 | console.log("翻译遗漏追踪", t("AppBpmn." + template)) 9 | template = t("AppBpmn." + template) || template; 10 | return template.replace(/{([^}]+)}/g, function (_: any, key: any) { 11 | return replacements[key] || '{' + key + '}'; 12 | }) 13 | }, [t]); 14 | 15 | return translate; 16 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetDiagramNode.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { x6NodesState } from "../recoil/atoms"; 5 | 6 | export function useGetDiagramNode(appId: ID) { 7 | const nodes = useRecoilValue(x6NodesState(appId)); 8 | 9 | const getNode = useCallback( 10 | (uuid: string, diagramUuid: string) => { 11 | return nodes.find( 12 | (node) => node.id === uuid && node.diagramUuid === diagramUuid 13 | ); 14 | }, 15 | [nodes] 16 | ); 17 | 18 | return getNode; 19 | } 20 | -------------------------------------------------------------------------------- /studio/src/model/notification.ts: -------------------------------------------------------------------------------- 1 | import { IUser } from "enthooks"; 2 | import { ID } from "shared"; 3 | import { IApp, IAppInput } from "./app"; 4 | import { IUserInput } from "./user"; 5 | 6 | export interface INotification { 7 | id: ID; 8 | text?: string; 9 | createdAt?: Date; 10 | read?: boolean; 11 | noticeType?: string; 12 | app?: IApp; 13 | user?: IUser; 14 | } 15 | 16 | export interface INotificationInput { 17 | id?: ID; 18 | text?: string; 19 | createdAt?: Date; 20 | read?: boolean; 21 | noticeType?: string; 22 | app?: { sync: IAppInput }; 23 | user?: { sync: IUserInput }; 24 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useDeleteCategory.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { IDeleteOptions, useDeleteById } from "enthooks/hooks/useDeleteById"; 3 | import { IProcessCategory } from "model"; 4 | 5 | export function useDeleteCategory(options?: IDeleteOptions): [ 6 | (id: ID) => void, 7 | { 8 | error?: Error, 9 | loading?: boolean, 10 | } 11 | ] { 12 | const [doDelete, { error, loading }] = useDeleteById("ProcessCategory", 13 | { 14 | ...options 15 | } 16 | ); 17 | 18 | return [doDelete, { error: error, loading: loading }] 19 | } -------------------------------------------------------------------------------- /studio/src/enthooks/awesome-graphql-client/util/gql.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Fake `graphql-tag`. 3 | * Recommended if you're using `graphql-tag` only for syntax highlighting 4 | * and static analysis such as linting and types generation. 5 | * It has less computational cost and makes overall smaller bundles. See: 6 | * https://github.com/lynxtaa/awesome-graphql-client#approach-2-use-fake-graphql-tag 7 | */ 8 | export const gql = (strings: TemplateStringsArray, ...values: any[]): string => { 9 | return strings 10 | .reduce((prev, curr, i) => prev + curr + (i in values ? values[i] : ''), '') 11 | .trim() 12 | } 13 | 14 | -------------------------------------------------------------------------------- /federation/reviews/graph/model/models_gen.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/99designs/gqlgen, DO NOT EDIT. 2 | 3 | package model 4 | 5 | type Product struct { 6 | Upc string `json:"upc"` 7 | Reviews []*Review `json:"reviews"` 8 | } 9 | 10 | func (Product) IsEntity() {} 11 | 12 | type Review struct { 13 | Body string `json:"body"` 14 | Author *User `json:"author"` 15 | Product *Product `json:"product"` 16 | } 17 | 18 | type User struct { 19 | ID string `json:"id"` 20 | Username string `json:"username"` 21 | Reviews []*Review `json:"reviews"` 22 | } 23 | 24 | func (User) IsEntity() {} 25 | -------------------------------------------------------------------------------- /studio/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/usePagesWithoutCategory.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { IPageCategory } from "model"; 3 | import { IAuthPage } from "./model"; 4 | 5 | export function usePagesWithoutCategory(pages:IAuthPage[], categories :IPageCategory[]) { 6 | const pagesWithoutCategory = useMemo(() => { 7 | const pgs = []; 8 | for (const page of pages || []) { 9 | if (!categories.find(category => category.uuid === page.page.categoryUuid)) { 10 | pgs.push(page) 11 | } 12 | } 13 | 14 | return pgs; 15 | }, [categories, pages]) 16 | 17 | return pagesWithoutCategory; 18 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/style.less: -------------------------------------------------------------------------------- 1 | .property-pannel-form{ 2 | padding: 0; 3 | .ant-collapse-content-box{ 4 | padding: 8px 16px; 5 | .ant-form-item{ 6 | margin-bottom: 8px; 7 | } 8 | } 9 | 10 | .element-summary{ 11 | padding: 8px 16px; 12 | display: flex; 13 | align-items: center; 14 | .element-icon{ 15 | display: flex; 16 | align-items: center; 17 | } 18 | .element-text{ 19 | padding-left: 8px; 20 | line-height: 14px; 21 | font-size: 12px; 22 | .element-type{ 23 | font-weight: bold; 24 | } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /gateway/middlewares/cors.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import "net/http" 4 | 5 | func CorsMiddleware(next http.Handler) http.Handler { 6 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 7 | //设置跨域 8 | w.Header().Set("Access-Control-Allow-Origin", "*") 9 | w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, OPTIONS") 10 | w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, leda-appid, leda-appname") 11 | //w.Header().Set("Access-Control-Allow-Credentials", "true") 12 | next.ServeHTTP(w, r) 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /services/models/modules/app/cache.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | var appLoaderCache sync.Map 8 | 9 | func ReloadApp(appId uint64) { 10 | if appLoader, ok := appLoaderCache.Load(appId); ok { 11 | appLoader.(*AppLoader).load(true) 12 | } 13 | } 14 | 15 | func ReloadAllApps() { 16 | appLoaderCache.Range(func(key interface{}, value interface{}) bool { 17 | value.(*AppLoader).load(true) 18 | return true 19 | }) 20 | } 21 | 22 | func ClearAppCache() { 23 | appLoaderCache.Range(func(key interface{}, value interface{}) bool { 24 | appLoaderCache.Delete(key) 25 | return true 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/items/AssgnmentItem.tsx: -------------------------------------------------------------------------------- 1 | import { Form, Input } from "antd"; 2 | import { useTranslation } from "react-i18next"; 3 | 4 | export const AssgnmentItem = (props: { element: any, modeler: any }) => { 5 | const { t } = useTranslation() 6 | return ( 7 | <> 8 | 12 | 13 | 14 | 18 | 19 | 20 | 21 | ) 22 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/plugins/context-pad/CustomContextPadProvider.ts: -------------------------------------------------------------------------------- 1 | export default class CustomContextPadProvider { 2 | constructor(contextPad: any) { 3 | contextPad.registerProvider(this); 4 | } 5 | 6 | getContextPadEntries() { 7 | return function (entries: any) { 8 | console.log("ContextPad 项目", entries) 9 | delete entries["append.condition-intermediate-event"]; 10 | delete entries["append.signal-intermediate-event"]; 11 | delete entries["append.receive-task"]; 12 | return entries; 13 | }; 14 | } 15 | } 16 | 17 | (CustomContextPadProvider as any).$inject = ["contextPad"]; 18 | -------------------------------------------------------------------------------- /services/models/middlewares/cors.go: -------------------------------------------------------------------------------- 1 | package middlewares 2 | 3 | import "net/http" 4 | 5 | func CorsMiddleware(next http.Handler) http.Handler { 6 | return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 7 | //设置跨域 8 | w.Header().Set("Access-Control-Allow-Origin", "*") 9 | w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, OPTIONS") 10 | w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, leda-appid, leda-appname") 11 | //w.Header().Set("Access-Control-Allow-Credentials", "true") 12 | next.ServeHTTP(w, r) 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /studio/src/dashboard/ConfigRoot.tsx: -------------------------------------------------------------------------------- 1 | import { ConfigProvider, theme } from "antd" 2 | import { memo } from "react" 3 | import { useRecoilValue } from "recoil" 4 | import { themeModeState } from "recoil/atoms" 5 | 6 | export const ConfigRoot = memo(( 7 | props: { 8 | children?: React.ReactNode 9 | } 10 | ) => { 11 | const themeMode = useRecoilValue(themeModeState) 12 | return ( 13 | 18 | { 19 | props.children 20 | } 21 | 22 | ) 23 | }) -------------------------------------------------------------------------------- /studio/src/plugins/framelayouts/pc/Container/view/style.less: -------------------------------------------------------------------------------- 1 | .appx-container{ 2 | width: 100%; 3 | margin-left: auto; 4 | box-sizing: border-box; 5 | margin-right: auto; 6 | display: block; 7 | padding-left: 16px; 8 | padding-right: 16px; 9 | } 10 | 11 | .appx-container.max-xs{ 12 | max-width: 575px; 13 | } 14 | .appx-container.max-sm{ 15 | max-width: 767px; 16 | } 17 | .appx-container.max-md{ 18 | max-width: 991px; 19 | } 20 | .appx-container.max-lg{ 21 | max-width: 1199px; 22 | } 23 | .appx-container.max-xl{ 24 | max-width: 1599px; 25 | } 26 | .appx-container.max-xxl{ 27 | width: 100%; 28 | } 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /studio/src/datasource/hooks/useGetPackageRootEntities.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { useSelectedAppId } from "plugin-sdk/contexts/desinger"; 4 | import { entitiesState } from "../recoil"; 5 | 6 | export function useGetPackageRootEntities() { 7 | const appId = useSelectedAppId(); 8 | const entities = useRecoilValue(entitiesState(appId)) 9 | 10 | const getPackageEntities = useCallback((packageUuid: string) => { 11 | return entities?.filter(entity => entity.packageUuid === packageUuid && entity.root) || []; 12 | }, [entities]) 13 | 14 | return getPackageEntities; 15 | } -------------------------------------------------------------------------------- /studio/src/designer/hooks/useShowError.ts: -------------------------------------------------------------------------------- 1 | import { message } from "antd"; 2 | import { useEffect } from "react"; 3 | import { useNavigate } from "react-router-dom"; 4 | import { CODE_LOGIN_EXPIRED, LOGIN_URL } from "../../consts"; 5 | import { GraphQLRequestError } from "../../enthooks"; 6 | 7 | export function useShowError(err?: GraphQLRequestError| Error) { 8 | const navigate = useNavigate(); 9 | useEffect(() => { 10 | if ((err as GraphQLRequestError)?.extensions?.["code"] === CODE_LOGIN_EXPIRED) { 11 | navigate(LOGIN_URL); 12 | } else if (err) { 13 | message.error(err.message) 14 | } 15 | }, [err, navigate]) 16 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/items/DocumentItem.tsx: -------------------------------------------------------------------------------- 1 | import { Form, Input } from "antd"; 2 | import React from "react"; 3 | import { useTranslation } from "react-i18next"; 4 | //import { MultiLangInput } from "plugins/inputs/components/pc/MultiLangInput/view"; 5 | 6 | export const DocumentItem = () => { 7 | const { t } = useTranslation() 8 | return ( 9 | 13 | {/* */} 14 | 15 | 16 | ) 17 | } -------------------------------------------------------------------------------- /studio/src/icons/PlugIcon.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { IconProps } from "./InterfaceIcon" 3 | 4 | const PlugIcon = (props: IconProps) => { 5 | return ( 6 | 9 | 10 | 11 | ) 12 | 13 | } 14 | 15 | export default PlugIcon 16 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useChangePackage.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react" 2 | import { useSetRecoilState } from "recoil"; 3 | import { useEdittingAppId } from "designer/hooks/useEdittingAppUuid"; 4 | import { PackageMeta } from "../meta/PackageMeta"; 5 | import { packagesState } from "../recoil/atoms"; 6 | 7 | export function useChangePackage() { 8 | const appId = useEdittingAppId(); 9 | const setPackages = useSetRecoilState(packagesState(appId)); 10 | const change = useCallback((pkg: PackageMeta) => { 11 | setPackages(packages => packages.map(pg => pg.uuid === pkg.uuid ? pkg : pg)) 12 | }, [setPackages]) 13 | 14 | return change; 15 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/X6EdgeMeta.ts: -------------------------------------------------------------------------------- 1 | import { Point } from "@antv/x6"; 2 | 3 | export type LabelPosition = { 4 | distance: number, 5 | offset: number, 6 | angle: number, 7 | } 8 | export interface X6EdgeMeta{ 9 | /** 对应关系 uuid */ 10 | id: string; 11 | 12 | /** 折点数据 */ 13 | vertices?: Point.PointLike[]; 14 | 15 | /** 源关系属性位置标签 */ 16 | roleOnSourcePosition?: LabelPosition; 17 | 18 | sourceMultiplicityPosition?: LabelPosition; 19 | 20 | /** 目标关系属性位置标签 */ 21 | roleOnTargetPosition?: LabelPosition; 22 | 23 | targetMultiplicityPosition?: LabelPosition; 24 | diagramUuid: string; 25 | sourceAnchor: any; 26 | targetAnchor: any; 27 | } -------------------------------------------------------------------------------- /studio/src/designer/hooks/useQueryAllTemplates.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "../../enthooks"; 2 | import { useMemo } from "react"; 3 | import { useQuery } from "../../enthooks/hooks/useQuery"; 4 | import { IUiFrame } from "../../model"; 5 | 6 | const templatesGql = gql` 7 | query{ 8 | templates{ 9 | nodes{ 10 | id 11 | title 12 | device 13 | imageUrl 14 | } 15 | total 16 | } 17 | } 18 | ` 19 | 20 | export function useQueryAllTemplates() { 21 | const args = useMemo(() => { 22 | return { 23 | gql: templatesGql, 24 | depEntityNames: ["Template"], 25 | } 26 | }, []) 27 | return useQuery(args) 28 | } -------------------------------------------------------------------------------- /studio/src/hooks/useQueryApps.ts: -------------------------------------------------------------------------------- 1 | import { gql, useQuery } from "enthooks"; 2 | import { IApp } from "model"; 3 | import { useMemo } from "react"; 4 | 5 | const appsGql = gql` 6 | query { 7 | apps{ 8 | nodes{ 9 | id 10 | uuid 11 | title 12 | imageUrl 13 | published 14 | } 15 | total 16 | } 17 | } 18 | ` 19 | 20 | export function useQueryApps() { 21 | const queryParams = useMemo(() => { 22 | return { 23 | gql: appsGql, 24 | depEntityNames: ["App"] 25 | } 26 | }, []) 27 | const { data, error, loading } = useQuery(queryParams) 28 | 29 | return { apps: data?.apps?.nodes, error, loading } 30 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/EntityTree/svgs.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo } from "react"; 2 | import { IconProps } from "icons/InterfaceIcon"; 3 | 4 | export const ClassIcon = memo((props: IconProps) => { 5 | return ( 6 | 7 | 21 | 22 | ) 23 | }) -------------------------------------------------------------------------------- /studio/src/datasource/model/IFieldSource.ts: -------------------------------------------------------------------------------- 1 | import { BaseDataType } from "shared/BaseDataType"; 2 | import { IDataBindSource } from "./IDataBindSource"; 3 | 4 | 5 | export enum FieldSourceType { 6 | Attribute = "Attribute", 7 | Method = "Method", 8 | Association = "Association" 9 | } 10 | 11 | export enum AssociationType { 12 | HasMany = "HasMany", 13 | HasOne = "HasOne" 14 | } 15 | 16 | export interface IFieldSource { 17 | name: string; 18 | label?: string; 19 | typeUuid?: string; 20 | typeEntityName?: string; 21 | sourceType: FieldSourceType; 22 | dataType?: BaseDataType; 23 | associationType?: AssociationType, 24 | dataBind?: IDataBindSource, 25 | } -------------------------------------------------------------------------------- /studio/src/enthooks/awesome-graphql-client/util/formatGetRequestUrl.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Returns URL for GraphQL GET Requests: 3 | * https://graphql.org/learn/serving-over-http/#get-request 4 | */ 5 | export function formatGetRequestUrl({ 6 | endpoint, 7 | query, 8 | variables, 9 | }: { 10 | endpoint: string 11 | query: string 12 | variables?: Record 13 | }): string { 14 | const searchParams = new URLSearchParams() 15 | searchParams.set('query', query) 16 | 17 | if (variables && Object.keys(variables).length > 0) { 18 | searchParams.set('variables', JSON.stringify(variables)) 19 | } 20 | 21 | return `${endpoint}?${searchParams.toString()}` 22 | } 23 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useFirstChildrenUuids.ts: -------------------------------------------------------------------------------- 1 | import { useRecoilValue } from "recoil"; 2 | import { ID } from "shared"; 3 | import { RelationType } from "../meta/RelationMeta"; 4 | import { relationsState } from "../recoil/atoms"; 5 | 6 | export function useFirstChildrenUuids(uuid: string, appId: ID) { 7 | const relations = useRecoilValue(relationsState(appId)); 8 | 9 | const children: string[] = []; 10 | for (const relation of relations) { 11 | if ( 12 | relation.targetId === uuid && 13 | relation.relationType === RelationType.INHERIT 14 | ) { 15 | children.push(relation.sourceId); 16 | } 17 | } 18 | return children; 19 | } 20 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/EmpertyCanvas.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | //import welcomeImage from "assets/img/welcome.png"; 3 | 4 | export default function EmpertyCanvas() { 5 | return ( 6 |
21 |
22 | ) 23 | } 24 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/useTriggerSelectedEvent.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { selectedElementState } from "../recoil/atoms"; 5 | import { EVENT_ELEMENT_SELECTED_CHANGE, triggerCanvasEvent } from "./events"; 6 | 7 | // atomFamily的effects没有实验成功,暂时用该钩子代替 8 | export function useTriggerSelectedEvent(appId: ID) { 9 | const selectedElement = useRecoilValue(selectedElementState(appId)); 10 | 11 | useEffect(() => { 12 | triggerCanvasEvent({ 13 | name: EVENT_ELEMENT_SELECTED_CHANGE, 14 | detail: selectedElement, 15 | }); 16 | }, [selectedElement]); 17 | } 18 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/useTriggerPressedLineTypeEvent.ts: -------------------------------------------------------------------------------- 1 | import { useEffect } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { pressedLineTypeState } from "../recoil/atoms"; 5 | import { EVENT_PRESSED_LINE_TYPE, triggerCanvasEvent } from "./events"; 6 | 7 | // atomFamily的effects没有实验成功,暂时用该钩子代替 8 | export function useTriggerPressedLineTypeEvent(appId: ID) { 9 | const pressedLineType = useRecoilValue(pressedLineTypeState(appId)); 10 | 11 | useEffect(() => { 12 | triggerCanvasEvent({ 13 | name: EVENT_PRESSED_LINE_TYPE, 14 | detail: pressedLineType, 15 | }); 16 | }, [pressedLineType]); 17 | } 18 | -------------------------------------------------------------------------------- /studio/src/enthooks/hooks/useQueryMe.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "enthooks"; 2 | import { ID } from "shared"; 3 | 4 | import { useRequest } from "./useRequest"; 5 | 6 | export interface IUser { 7 | id: ID; 8 | name: string; 9 | loginName: string; 10 | isSupper?: boolean; 11 | isDemo?: boolean; 12 | } 13 | 14 | const queryGql = gql` 15 | query{ 16 | me{ 17 | id 18 | name 19 | loginName 20 | isSupper 21 | isDemo 22 | } 23 | } 24 | `; 25 | 26 | export function useQueryMe(): { 27 | loading?: boolean, 28 | error?: Error, 29 | me?: IUser 30 | } { 31 | const { data, error, loading } = useRequest(queryGql); 32 | return { me: data?.me, error, loading } 33 | } -------------------------------------------------------------------------------- /studio/src/plugin-sdk/locales/styleLocales.ts: -------------------------------------------------------------------------------- 1 | export const styleLocales = { 2 | 'zh-CN': { 3 | width: '宽度', 4 | height: '高度', 5 | display: '展示', 6 | background: '背景', 7 | boxShadow: '阴影', 8 | font: '字体', 9 | margin: '外边距', 10 | padding: '内边距', 11 | borderRadius: '圆角', 12 | border: '边框', 13 | opacity: '透明度', 14 | }, 15 | 'en-US': { 16 | width: 'Width', 17 | height: 'Height', 18 | display: 'Display', 19 | background: 'Background', 20 | boxShadow: 'Box Shadow', 21 | font: 'Font', 22 | margin: 'Margin', 23 | padding: 'Padding', 24 | borderRadius: 'Radius', 25 | border: 'Border', 26 | opacity: 'Opacity', 27 | } 28 | } -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useAuthPages.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { IPage } from "model"; 3 | import { IAuthPage } from "./model"; 4 | import { useParsePageComponents } from "./useParsePageComponents"; 5 | 6 | export function useAuthPages(pages: IPage[]) { 7 | const parse = useParsePageComponents(); 8 | const authPages = useMemo(() => { 9 | const pgs: IAuthPage[] = [] 10 | for (const page of pages) { 11 | const coms = parse(page) 12 | if (coms.length > 0) { 13 | pgs.push({ 14 | page, 15 | components: coms, 16 | }) 17 | } 18 | } 19 | 20 | return pgs; 21 | 22 | }, [pages, parse]) 23 | return authPages; 24 | } -------------------------------------------------------------------------------- /studio/src/designer/index.tsx: -------------------------------------------------------------------------------- 1 | import { memo } from "react" 2 | import { Outlet } from "react-router-dom"; 3 | import { useQueryApp } from "./hooks/useQueryApp"; 4 | import { useShowError } from 'designer/hooks/useShowError'; 5 | import { useEdittingAppId } from "designer/hooks/useEdittingAppUuid"; 6 | import AppDesignerRoot from "./AppDesignerRoot"; 7 | 8 | const AppDesigner = memo(() => { 9 | const appId = useEdittingAppId(); 10 | const { app, error } = useQueryApp(appId) 11 | 12 | useShowError(error); 13 | 14 | return ( 15 | app ? 16 | 17 | 18 | 19 | : <> 20 | ) 21 | }) 22 | 23 | export default AppDesigner; -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetSourceRelations.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { RelationType } from "../meta/RelationMeta"; 5 | import { relationsState } from "../recoil/atoms"; 6 | 7 | export function useGetSourceRelations(appId: ID) { 8 | const relations = useRecoilValue(relationsState(appId)); 9 | 10 | const getRelations = useCallback((entityUuid: string,)=>{ 11 | return relations.filter( 12 | (relation) => 13 | relation.sourceId === entityUuid && 14 | relation.relationType !== RelationType.INHERIT 15 | ); 16 | }, [relations]) 17 | 18 | return getRelations; 19 | } 20 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useMethod.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { classesState } from "../recoil/atoms"; 5 | 6 | export function useMethod(uuid: string, appId: ID) { 7 | const classes = useRecoilValue(classesState(appId)); 8 | 9 | const rt = useMemo(() => { 10 | for (const cls of classes) { 11 | if (!cls.methods) { 12 | continue; 13 | } 14 | for (const method of cls.methods) { 15 | if (method.uuid === uuid) { 16 | return { cls, method }; 17 | } 18 | } 19 | } 20 | 21 | return {}; 22 | }, [classes, uuid]); 23 | 24 | return rt; 25 | } 26 | -------------------------------------------------------------------------------- /studio/src/model/plugin.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { IApp, IAppInput } from "./app"; 3 | 4 | export enum PluginType { 5 | uploaded = "uploaded", 6 | debug = "debug", 7 | market = "market" 8 | } 9 | 10 | export interface IPluginInfo { 11 | id?: ID; 12 | app?: IApp; 13 | title?: string; 14 | url?: string; 15 | pluginId?: string, 16 | type?: PluginType, 17 | description?: string, 18 | version?: string, 19 | } 20 | 21 | 22 | export interface IPluginInfoInput { 23 | id?: ID; 24 | app?: { 25 | sync: IAppInput 26 | }; 27 | title?: string; 28 | url?: string; 29 | type?: PluginType, 30 | description?: string; 31 | version?: string; 32 | pluginId: string; 33 | } 34 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useProcessesWithoutCategory.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useCategories } from "./useCategories"; 3 | import { useProcesses } from "./useProcesses"; 4 | 5 | export function useProcessesWithoutCategory() { 6 | const processes = useProcesses(); 7 | const categories = useCategories(); 8 | 9 | const processessWithoutCategory = useMemo(() => { 10 | const pcs = []; 11 | for (const process of processes || []) { 12 | if (!categories.find(category => category.uuid === process.categoryUuid)) { 13 | pcs.push(process) 14 | } 15 | } 16 | 17 | return pcs; 18 | }, [categories, processes]) 19 | 20 | return processessWithoutCategory; 21 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/recoil/atoms.ts: -------------------------------------------------------------------------------- 1 | import { atomFamily } from "recoil"; 2 | import { IProcess, IProcessCategory } from "model"; 3 | import { ID } from "shared"; 4 | 5 | export const selectedBpmnProcessIdState = atomFamily({ 6 | key: "bpmn.selectedProcessId", 7 | default: undefined, 8 | }); 9 | 10 | export const categoriesState = atomFamily({ 11 | key: "bpmn.categories", 12 | default: [], 13 | }); 14 | 15 | export const processesState = atomFamily({ 16 | key: "bpmn.processes", 17 | default: [], 18 | }) 19 | 20 | 21 | export const minMapState = atomFamily({ 22 | key: "bpmn.minMap", 23 | default: false, 24 | }); -------------------------------------------------------------------------------- /federation/reviews/graph/handler.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/99designs/gqlgen/graphql/handler" 7 | "github.com/99designs/gqlgen/graphql/handler/debug" 8 | 9 | "github.com/wundergraph/graphql-go-tools/examples/federation/reviews/graph/generated" 10 | ) 11 | 12 | type EndpointOptions struct { 13 | EnableDebug bool 14 | } 15 | 16 | var TestOptions = EndpointOptions{ 17 | EnableDebug: false, 18 | } 19 | 20 | func GraphQLEndpointHandler(opts EndpointOptions) http.Handler { 21 | srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &Resolver{}})) 22 | if opts.EnableDebug { 23 | srv.Use(&debug.Tracer{}) 24 | } 25 | 26 | return srv 27 | } 28 | -------------------------------------------------------------------------------- /federation/accounts/graph/handler.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import ( 4 | "net/http" 5 | 6 | "github.com/99designs/gqlgen/graphql/handler" 7 | "github.com/99designs/gqlgen/graphql/handler/debug" 8 | 9 | "github.com/wundergraph/graphql-go-tools/examples/federation/accounts/graph/generated" 10 | ) 11 | 12 | type EndpointOptions struct { 13 | EnableDebug bool 14 | } 15 | 16 | var TestOptions = EndpointOptions{ 17 | EnableDebug: false, 18 | } 19 | 20 | func GraphQLEndpointHandler(opts EndpointOptions) http.Handler { 21 | srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &Resolver{}})) 22 | if opts.EnableDebug { 23 | srv.Use(&debug.Tracer{}) 24 | } 25 | 26 | return srv 27 | } 28 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetTargetRelations.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { RelationType } from "../meta/RelationMeta"; 5 | import { relationsState } from "../recoil/atoms"; 6 | 7 | export function useGetTargetRelations(appId: ID) { 8 | const relations = useRecoilValue(relationsState(appId)); 9 | 10 | const getTargetRelations = useCallback((entityUuid: string,)=>{ 11 | return relations.filter( 12 | (relation) => 13 | relation.targetId === entityUuid && 14 | relation.relationType !== RelationType.INHERIT 15 | ); 16 | }, [relations]) 17 | 18 | 19 | return getTargetRelations; 20 | } 21 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/elements/useAssociation.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | import { IElement } from "./IElement"; 4 | 5 | export function useAssociation(element: any, modeler: any): IElement { 6 | const { t } = useTranslation(); 7 | 8 | const iElement: IElement = useMemo(() => { 9 | return { 10 | type: t("AppBpmn.Association"), 11 | name: false, 12 | icon: , 13 | } 14 | }, [t]); 15 | 16 | return iElement; 17 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useAttribute.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { classesState } from "../recoil/atoms"; 5 | 6 | export function useAttribute(uuid: string, appId: ID) { 7 | const classes = useRecoilValue(classesState(appId)); 8 | 9 | const rt = useMemo(() => { 10 | for (const cls of classes) { 11 | if (!cls.attributes) { 12 | continue; 13 | } 14 | for (const attribute of cls.attributes) { 15 | if (attribute.uuid === uuid) { 16 | return { cls, attribute }; 17 | } 18 | } 19 | } 20 | 21 | return {}; 22 | }, [classes, uuid]); 23 | 24 | return rt; 25 | } 26 | -------------------------------------------------------------------------------- /federation/reviews/graph/reviews.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | import "github.com/wundergraph/graphql-go-tools/examples/federation/reviews/graph/model" 4 | 5 | var reviews = []*model.Review{ 6 | { 7 | Body: "A highly effective form of birth control.", 8 | Product: &model.Product{Upc: "top-1"}, 9 | Author: &model.User{ID: "1234"}, 10 | }, 11 | { 12 | Body: "Fedoras are one of the most fashionable hats around and can look great with a variety of outfits.", 13 | Product: &model.Product{Upc: "top-2"}, 14 | Author: &model.User{ID: "1234"}, 15 | }, 16 | { 17 | Body: "This is the last straw. Hat you will wear. 11/10", 18 | Product: &model.Product{Upc: "top-3"}, 19 | Author: &model.User{ID: "7777"}, 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /studio/src/bpmn/decorators/inject.decorator.ts: -------------------------------------------------------------------------------- 1 | export type InjectableComponent = 2 | | 'eventBus' 3 | | 'create' 4 | | 'elementFactory' 5 | | 'elementRegistry' 6 | | 'lassoTool' 7 | | 'palette' 8 | | 'styles' 9 | | 'pathMap' 10 | | 'canvas' 11 | | 'defaultRenderer' 12 | | 'textRenderer' 13 | | 'connect' 14 | | 'contextPad' 15 | | 'modeling' 16 | | 'directEditing' 17 | | 'resizeHandles' 18 | | 'commandStack' 19 | | 'config.textRenderer' 20 | | string; 21 | 22 | export function Inject(injection: InjectableComponent, ...others: InjectableComponent[]) { 23 | return T>(ctor: T) => { 24 | // @ts-ignore 25 | ctor.$inject = [injection, ...others]; 26 | }; 27 | } 28 | -------------------------------------------------------------------------------- /studio/src/datasource/hooks/createObjectFieldNode.ts: -------------------------------------------------------------------------------- 1 | import { Kind, ObjectFieldNode } from "graphql"; 2 | import { createObjectValueNode } from "./createObjectValueNode"; 3 | 4 | export const createObjectFieldNode = (name: string, operator: string, value: any): ObjectFieldNode => { 5 | return { 6 | kind: Kind.OBJECT_FIELD, 7 | name: { 8 | kind: Kind.NAME, 9 | value: name, 10 | }, 11 | value: { 12 | kind: Kind.OBJECT, 13 | fields: [ 14 | { 15 | kind: Kind.OBJECT_FIELD, 16 | name: { 17 | kind: Kind.NAME, 18 | value: operator 19 | }, 20 | value: createObjectValueNode(value) 21 | } 22 | ] 23 | } 24 | }; 25 | }; 26 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useRoleName.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | import { GUEST_ROLE_ID } from "consts"; 4 | import { useParseLangMessage } from "plugin-sdk"; 5 | import { ID } from "shared"; 6 | import { useRole } from "./useRole"; 7 | 8 | export function useRoleName(roleId: ID) { 9 | const role = useRole(roleId); 10 | const p = useParseLangMessage(); 11 | const { t } = useTranslation(); 12 | 13 | const roleName = useMemo(() => { 14 | if (role?.name) { 15 | return p(role.name); 16 | } 17 | 18 | if (roleId === GUEST_ROLE_ID) { 19 | return t("Auth.Guest"); 20 | } 21 | }, [p, role?.name, roleId, t]) 22 | 23 | return roleName; 24 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/Type.ts: -------------------------------------------------------------------------------- 1 | import { BaseDataType } from "shared/BaseDataType"; 2 | 3 | /** 4 | * 字段类型,目前版本仅支持这些类型,后续可以扩展 5 | */ 6 | export enum ExtendType { 7 | JSON = "JSON", 8 | ValueObject = "ValueObject", 9 | Entity = "Entity", 10 | 11 | IDArray = "ID[]", 12 | IntArray = "Int[]", 13 | FloatArray = "Float[]", 14 | StringArray = "String[]", 15 | DateArray = "Date[]", 16 | EnumArray = "EnumArray", 17 | JSONArray = "JSONArray", 18 | ValueObjectArray = "ValueObjectArray", 19 | EntityArray = "EntityArray", 20 | File = "File", 21 | Password = "Password", 22 | Uuid = "Uuid" 23 | } 24 | 25 | export type Type = ExtendType | BaseDataType 26 | 27 | export const Types = { ...ExtendType, ...BaseDataType }; -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useCheckOrchestrationName.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { orchestrationsState } from "../recoil/atoms"; 5 | 6 | export function useCheckOrchestrationName(appId: ID) { 7 | const orchestrations = useRecoilValue(orchestrationsState(appId)); 8 | 9 | /** 10 | * propertyUuid 如果关联性质,为类UUID+关联UUID 11 | */ 12 | const checkName = useCallback( 13 | (orchestrationName: string, orchestrationUuid: string) => { 14 | return !orchestrations.find((ors) => ors.name === orchestrationName && ors.uuid !== orchestrationUuid); 15 | }, 16 | [orchestrations] 17 | ); 18 | 19 | return checkName; 20 | } 21 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useDeletePackage.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { useBackupSnapshot } from "./useBackupSnapshot"; 3 | import { useCallback } from 'react'; 4 | import { useSetRecoilState } from 'recoil'; 5 | import { packagesState } from './../recoil/atoms'; 6 | 7 | /** 8 | * 并没有删除包下面的元素,保存数据时需要过滤一下 9 | * @returns 10 | */ 11 | export function useDeletePackage(appId: ID) { 12 | const setPackages = useSetRecoilState(packagesState(appId)); 13 | const backup = useBackupSnapshot(appId); 14 | 15 | const deletePackage = useCallback((uuid: string) => { 16 | backup() 17 | setPackages(packages => packages.filter(pkg => pkg.uuid !== uuid)) 18 | }, [backup, setPackages]) 19 | 20 | return deletePackage 21 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/usePublished.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useQueryApp } from "designer/hooks/useQueryApp"; 3 | import { ID } from "shared"; 4 | import dayjs from "dayjs"; 5 | 6 | export function usePublished(appId: ID) { 7 | const { app } = useQueryApp(appId) 8 | 9 | const published = useMemo(() => { 10 | if (!app) { 11 | return false; 12 | } 13 | 14 | if (app.publishMetaAt && (dayjs(app?.saveMetaAt).diff(dayjs(app?.publishMetaAt)) <= 0)) { 15 | return true; 16 | } 17 | 18 | if (!app.saveMetaAt) { 19 | return true; 20 | } 21 | if (!app.publishMetaAt && app.saveMetaAt) { 22 | return false; 23 | } 24 | }, [app]) 25 | 26 | 27 | return published; 28 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useCreateClassMethod.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { ID } from "shared"; 3 | import { ClassMeta } from "../meta/ClassMeta"; 4 | import { useChangeClass } from "./useChangeClass"; 5 | import { useCreateMethod } from "./useCreateMethod"; 6 | 7 | export function useCreateClassMethod(appId: ID) { 8 | const changeClass = useChangeClass(appId); 9 | const createMethod = useCreateMethod(appId); 10 | const createClassMethod = useCallback( 11 | (cls: ClassMeta) => { 12 | const method = createMethod(cls.methods); 13 | 14 | changeClass({ ...cls, methods: [...cls.methods||[], method] }); 15 | }, 16 | [changeClass, createMethod] 17 | ); 18 | 19 | return createClassMethod; 20 | } 21 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/meta/Meta.ts: -------------------------------------------------------------------------------- 1 | import { RelationMeta } from "./RelationMeta"; 2 | import { PackageMeta } from "./PackageMeta"; 3 | import { ClassMeta } from "./ClassMeta"; 4 | import { DiagramMeta } from "./DiagramMeta"; 5 | import { X6NodeMeta } from "./X6NodeMeta"; 6 | import { X6EdgeMeta } from "./X6EdgeMeta"; 7 | import { CodeMeta } from "./CodeMeta"; 8 | import { OrchestrationMeta } from "./OrchestrationMeta"; 9 | 10 | export interface MetaContent { 11 | packages: PackageMeta[]; 12 | classes?: ClassMeta[]; 13 | diagrams?: DiagramMeta[]; 14 | relations: RelationMeta[]; 15 | codes?: CodeMeta[]; 16 | orchestrations?: OrchestrationMeta[]; 17 | x6Nodes: X6NodeMeta[]; 18 | x6Edges: X6EdgeMeta[]; 19 | } 20 | 21 | export const CONST_ID = "id" 22 | -------------------------------------------------------------------------------- /studio/src/designer/hooks/useUpdatePage.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { IPostOptions, usePostOne } from "../../enthooks/hooks/usePostOne"; 3 | import { IPage } from "../../model"; 4 | import { IPageInput } from "../../model"; 5 | 6 | export function useUpdatePage(options?: IPostOptions): [ 7 | (page: IPageInput) => void, 8 | { loading?: boolean; error?: Error } 9 | ] { 10 | const [post, { error, loading }] = usePostOne("Page", 11 | { 12 | ...options, 13 | fieldsGql: "id title schemaJson" 14 | } 15 | ) 16 | 17 | const update = useCallback((page: IPageInput) => { 18 | post({ 19 | ...page, 20 | }) 21 | }, [post]); 22 | 23 | return [update, { error: error, loading: loading }] 24 | } -------------------------------------------------------------------------------- /studio/src/shared/index.ts: -------------------------------------------------------------------------------- 1 | import { v4 as uuidv4 } from 'uuid'; 2 | 3 | var idSeed = new Date().getTime() 4 | export type ID = string; 5 | 6 | export function createId(): ID { 7 | idSeed = new Date().getTime() 8 | return idSeed + "" 9 | } 10 | 11 | export const createUuid = () => { 12 | return uuidv4(); 13 | }; 14 | 15 | export const stringToObj = (str?: string) => { 16 | if (!str) { 17 | return {} 18 | } 19 | 20 | const obj = JSON.parse(str); 21 | 22 | return obj; 23 | } 24 | 25 | export const objToString = (obj?: any) => { 26 | if (!obj) { 27 | return obj; 28 | } 29 | 30 | return JSON.stringify(obj); 31 | } 32 | 33 | export const httpPrefix = (url: string) => { 34 | return url.startsWith("https://") ? "https://" : "http://" 35 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useQueryOneProcess.ts: -------------------------------------------------------------------------------- 1 | import { gql, useQueryOne } from "enthooks"; 2 | import { useMemo } from "react"; 3 | import { IProcess } from "model/process"; 4 | 5 | const processGql = gql` 6 | query ($id:ID!){ 7 | oneProcess(where:{ 8 | id:{ 9 | _eq:$id 10 | } 11 | }){ 12 | id 13 | name 14 | uuid 15 | categoryUuid 16 | xml 17 | } 18 | } 19 | ` 20 | 21 | export function useQueryOneProcess(id?: string) { 22 | const input = useMemo(() => ( 23 | { 24 | gql: id && processGql, 25 | params: { id }, 26 | depEntityNames: [] 27 | } 28 | ), [id]); 29 | 30 | const { data, error, loading } = useQueryOne(input); 31 | 32 | return { process: data?.oneProcess, error, loading } 33 | } -------------------------------------------------------------------------------- /studio/src/designer/hooks/useQueryPage.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "../../enthooks"; 2 | import { useMemo } from "react"; 3 | import { useQueryOne } from "../../enthooks/hooks/useQueryOne"; 4 | import { IPage } from "../../model"; 5 | 6 | const pageGql = gql` 7 | query ($id:ID!){ 8 | onePage(where:{ 9 | id:{ 10 | _eq:$id 11 | } 12 | }){ 13 | id 14 | title 15 | schemaJson 16 | } 17 | } 18 | ` 19 | 20 | export function useQueryPage(id?: string) { 21 | const input = useMemo(() => ( 22 | { 23 | gql: id && pageGql, 24 | params: { id }, 25 | depEntityNames: ["Page"] 26 | } 27 | ), [id]); 28 | 29 | const { data, error, loading } = useQueryOne(input); 30 | 31 | return { page: data?.onePage, error, loading } 32 | } -------------------------------------------------------------------------------- /studio/src/enthooks/hooks/useLogout.ts: -------------------------------------------------------------------------------- 1 | import { useSetToken } from "../context"; 2 | import { gql } from 'enthooks' 3 | import { useLazyRequest } from "./useLazyRequest"; 4 | import { useCallback } from "react"; 5 | 6 | const logoutMutation = gql` 7 | mutation { 8 | logout 9 | } 10 | `; 11 | 12 | export function useLogout(): [ 13 | () => void, 14 | { loading?: boolean; error?: Error } 15 | ] { 16 | 17 | const setConfigToken = useSetToken(); 18 | 19 | const [doLogout, { loading, error }] = useLazyRequest({ 20 | onCompleted: (data: any) => { 21 | setConfigToken(undefined); 22 | }, 23 | }) 24 | 25 | const logout = useCallback(()=>{ 26 | doLogout(logoutMutation) 27 | }, [doLogout]) 28 | 29 | return [logout, { loading, error }]; 30 | } 31 | -------------------------------------------------------------------------------- /federation/accounts/server.go: -------------------------------------------------------------------------------- 1 | //go:generate go run -mod=mod github.com/99designs/gqlgen 2 | package main 3 | 4 | import ( 5 | "log" 6 | "net/http" 7 | "os" 8 | 9 | "github.com/99designs/gqlgen/graphql/playground" 10 | 11 | "github.com/wundergraph/graphql-go-tools/examples/federation/accounts/graph" 12 | ) 13 | 14 | const defaultPort = "4001" 15 | 16 | func main() { 17 | port := os.Getenv("PORT") 18 | if port == "" { 19 | port = defaultPort 20 | } 21 | 22 | http.Handle("/", playground.Handler("GraphQL playground", "/query")) 23 | http.Handle("/query", graph.GraphQLEndpointHandler(graph.EndpointOptions{EnableDebug: true})) 24 | 25 | log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) 26 | log.Fatal(http.ListenAndServe(":"+port, nil)) 27 | } 28 | -------------------------------------------------------------------------------- /federation/reviews/server.go: -------------------------------------------------------------------------------- 1 | //go:generate go run -mod=mod github.com/99designs/gqlgen 2 | package main 3 | 4 | import ( 5 | "log" 6 | "net/http" 7 | "os" 8 | 9 | "github.com/99designs/gqlgen/graphql/playground" 10 | 11 | "github.com/wundergraph/graphql-go-tools/examples/federation/reviews/graph" 12 | ) 13 | 14 | const defaultPort = "4003" 15 | 16 | func main() { 17 | port := os.Getenv("PORT") 18 | if port == "" { 19 | port = defaultPort 20 | } 21 | 22 | http.Handle("/", playground.Handler("GraphQL playground", "/query")) 23 | http.Handle("/query", graph.GraphQLEndpointHandler(graph.EndpointOptions{EnableDebug: true})) 24 | 25 | log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) 26 | log.Fatal(http.ListenAndServe(":"+port, nil)) 27 | } 28 | -------------------------------------------------------------------------------- /studio/src/enthooks/hooks/useImportApp.ts: -------------------------------------------------------------------------------- 1 | import { RequestOptions, useLazyRequest } from "enthooks"; 2 | import { useCallback } from "react"; 3 | import { ID } from "shared"; 4 | 5 | const importGql = ` 6 | mutation ($appFile:Upload, $appId:ID){ 7 | importApp(appFile:$appFile, appId:$appId) 8 | } 9 | ` 10 | 11 | export function useImportApp(options?: RequestOptions): [ 12 | (file: File, appId?: ID) => void, 13 | { 14 | error?: Error, 15 | loading?: boolean, 16 | } 17 | ] { 18 | 19 | const [doImport, { error, loading }] = useLazyRequest(options) 20 | 21 | const importApp = useCallback((appFile: File, appId?: ID) => { 22 | doImport(importGql, { appFile, appId }) 23 | }, [doImport]); 24 | 25 | return [importApp, { error, loading }]; 26 | } 27 | -------------------------------------------------------------------------------- /studio/src/enthooks/hooks/useExportApp.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react" 2 | import { ID } from "shared" 3 | import { gql } from "../awesome-graphql-client"; 4 | import { RequestOptions, useLazyRequest } from "./useLazyRequest"; 5 | 6 | const queryGql = gql` 7 | query ($snapshotId: ID!) { 8 | exportApp(snapshotId: $snapshotId) 9 | } 10 | `; 11 | 12 | export function useExportApp(options?: RequestOptions): [ 13 | (snapshotId: ID) => void, 14 | { 15 | error?: Error, 16 | loading?: boolean, 17 | } 18 | ] { 19 | const [doExport, { error, loading }] = useLazyRequest(options) 20 | 21 | const exportApp = useCallback((snapshotId: ID) => { 22 | return doExport(queryGql, { snapshotId }) 23 | }, [doExport]) 24 | 25 | return [exportApp, { error, loading }] 26 | } -------------------------------------------------------------------------------- /studio/src/datasource/hooks/getParentClasses.ts: -------------------------------------------------------------------------------- 1 | import { ClassMeta, RelationMeta, RelationType } from "designer/AppUml/meta"; 2 | 3 | 4 | export const getParentClasses = (classUuid: string, classMetas: ClassMeta[], relations: RelationMeta[]) => { 5 | const classes: ClassMeta[] = []; 6 | for (const relation of relations) { 7 | if (relation.relationType === RelationType.INHERIT) { 8 | if (relation.sourceId === classUuid) { 9 | const parent = classMetas.find(cls => cls.uuid === relation.targetId); 10 | if (parent) { 11 | classes.push(parent); 12 | const parentsOfParent = getParentClasses(parent.uuid, classMetas, relations); 13 | classes.push(...parentsOfParent); 14 | } 15 | } 16 | } 17 | } 18 | return classes; 19 | }; 20 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useAuthCategories.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { IPageCategory } from "model"; 3 | import { IAuthPage } from "./model"; 4 | import { useGetCategoryPages } from "./useGetCategoryPages"; 5 | 6 | export function useAuthCategories(categories: IPageCategory[], authPages: IAuthPage[]) { 7 | const getPages = useGetCategoryPages(authPages); 8 | const authCategories = useMemo(() => { 9 | const athCats = []; 10 | for (const category of categories) { 11 | const pgs = getPages(category.uuid); 12 | if (pgs.length > 0) { 13 | athCats.push({ 14 | category, 15 | pages: pgs, 16 | }) 17 | } 18 | } 19 | return athCats; 20 | }, [categories, getPages]) 21 | 22 | return authCategories; 23 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useCreateClassAttribute.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { ID } from "shared"; 3 | import { ClassMeta } from "../meta/ClassMeta"; 4 | import { useChangeClass } from "./useChangeClass"; 5 | import { useCreateAttribute } from "./useCreateAttribute"; 6 | 7 | export function useCreateClassAttribute(appId: ID) { 8 | const changeClass = useChangeClass(appId); 9 | const createAttribute = useCreateAttribute(appId); 10 | const createClassAttribute = useCallback( 11 | (cls: ClassMeta) => { 12 | const attr = createAttribute(cls.attributes); 13 | changeClass({ ...cls, attributes: [...cls.attributes, attr] }); 14 | return attr 15 | }, 16 | [changeClass, createAttribute] 17 | ); 18 | 19 | return createClassAttribute; 20 | } 21 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useDeployProcess.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "enthooks"; 2 | import { useCallback } from "react"; 3 | import { ID } from "shared"; 4 | import { RequestOptions, useLazyRequest } from "enthooks/hooks/useLazyRequest"; 5 | 6 | const deployGql = gql` 7 | mutation ($id:ID!) { 8 | deployProcess (id:$id) 9 | } 10 | `; 11 | 12 | export function useDeployProcess( 13 | id: ID, 14 | options?: RequestOptions 15 | ): [ 16 | () => void, 17 | { loading: boolean|undefined; error: Error | undefined } 18 | ] { 19 | 20 | const [doDeploy, { loading, error }] = useLazyRequest(options) 21 | 22 | const deploy = useCallback(() => { 23 | doDeploy(id ? deployGql : undefined, { id }) 24 | }, [id, doDeploy]); 25 | 26 | return [deploy, { loading, error }]; 27 | } 28 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useGetPackageCanAuthClasses.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { classesState } from "../../AppUml/recoil/atoms"; 4 | import { ID } from "shared"; 5 | import { StereoType } from "../../AppUml/meta/ClassMeta"; 6 | 7 | export function useGetPackageCanAuthClasses(appId:ID) { 8 | 9 | const classes = useRecoilValue(classesState(appId)); 10 | 11 | const getClasses = useCallback((packageUuid: ID) => { 12 | return classes.filter( 13 | cls => cls.packageUuid === packageUuid && 14 | (cls.stereoType === StereoType.Entity || 15 | //cls.stereoType === StereoType.Service || 16 | cls.stereoType === StereoType.ThirdParty 17 | )) 18 | }, [classes]) 19 | 20 | return getClasses; 21 | } -------------------------------------------------------------------------------- /studio/src/Login/LoggedInPanel.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { memo } from "react" 3 | import { Outlet } from "react-router-dom" 4 | import { useQueryMe } from "../enthooks/hooks/useQueryMe"; 5 | import { useLoginCheck } from "../designer/hooks/useLoginCheck"; 6 | import { useShowError } from "designer/hooks/useShowError"; 7 | import { UserContext } from "plugin-sdk/contexts/login"; 8 | import { CenterSpin } from "common/CenterSpin"; 9 | 10 | export const LoggedInPanel = memo(() => { 11 | useLoginCheck(); 12 | const { me, loading, error } = useQueryMe(); 13 | useShowError(error); 14 | 15 | return ( 16 | loading 17 | ? 18 | 19 | : 20 | 21 | 22 | 23 | ) 24 | }) -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/usePublishMeta.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "enthooks"; 2 | import { useCallback } from "react"; 3 | import { RequestOptions, useLazyRequest } from "enthooks/hooks/useLazyRequest"; 4 | import { ID } from "shared"; 5 | 6 | const publishGql = gql` 7 | mutation publish($appId:ID!) { 8 | publish (appId:$appId) 9 | } 10 | `; 11 | 12 | export function usePublishMeta( 13 | appId: ID, 14 | options?: RequestOptions 15 | ): [ 16 | () => void, 17 | { loading: boolean | undefined; error: Error | undefined } 18 | ] { 19 | 20 | const [doPublish, { loading, error }] = useLazyRequest(options) 21 | 22 | const publish = useCallback(() => { 23 | doPublish(publishGql, { appId }) 24 | }, [appId, doPublish]); 25 | 26 | return [publish, { loading, error }]; 27 | } 28 | -------------------------------------------------------------------------------- /studio/src/plugin-sdk/model/IMenuNode.ts: -------------------------------------------------------------------------------- 1 | import { IIcon } from "../icon/model"; 2 | 3 | export enum MenuItemType { 4 | Group = "Group", 5 | Divider = "Divider", 6 | Link = "Link", 7 | Item = "Item", 8 | } 9 | 10 | export interface IMenuBadge { 11 | color?: "primary" | "secondary" | "default"; 12 | field?: string; 13 | size?: "small" | "medium"; 14 | } 15 | 16 | export interface IMenuItem { 17 | uuid: string; 18 | type: MenuItemType; 19 | title?: string; 20 | icon?: IIcon; 21 | badge?: IMenuBadge; 22 | //chip?:IMenuChip, 23 | children?: IMenuItem[]; 24 | link?: string; 25 | //auths?: RxAuth[]; 26 | route?: { 27 | pageUuid?: string; 28 | payload?: any; 29 | }; 30 | } 31 | 32 | export interface IMenuNode { 33 | parentId?: string; 34 | childIds: string[]; 35 | meta: IMenuItem; 36 | } 37 | -------------------------------------------------------------------------------- /studio/src/dashboard/AppManager/hooks/useAppOpenFile.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | 3 | export async function getTheFiles(accept: string, multiple?: boolean) { 4 | // open file picker 5 | const fileHandles = await (window as any).showOpenFilePicker({ 6 | types: [{ 7 | accept: { 8 | "file/*": accept?.split(",") 9 | }, 10 | }], 11 | excludeAcceptAllOption: false, 12 | multiple: multiple, 13 | }); 14 | 15 | return fileHandles; 16 | } 17 | 18 | export function useAppOpenFile() { 19 | const open = useCallback(async () => { 20 | const fileHandles = await getTheFiles(".zip", false) 21 | const files = await fileHandles.map(async (fileHandle: any) => { 22 | return await fileHandle.getFile(); 23 | }) 24 | return files?.[0] 25 | }, []) 26 | 27 | return open; 28 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useRootClasses.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { StereoType } from "../meta/ClassMeta"; 5 | import { classesState } from "../recoil/atoms"; 6 | import { useGetFirstParentUuids } from "./useGetFirstParentUuids"; 7 | 8 | export function useRootClasses(appId: ID) { 9 | const classes = useRecoilValue(classesState(appId)); 10 | const getParentuuids = useGetFirstParentUuids(appId); 11 | const entities = useMemo(() => { 12 | return classes.filter( 13 | (cls) => 14 | (cls.stereoType === StereoType.Entity || 15 | cls.stereoType === StereoType.Abstract) && 16 | getParentuuids(cls.uuid).length === 0 17 | ); 18 | }, [classes, getParentuuids]); 19 | 20 | return entities; 21 | } 22 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetFirstParentUuids.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { RelationType } from "../meta/RelationMeta"; 5 | import { relationsState } from "../recoil/atoms"; 6 | 7 | export function useGetFirstParentUuids(appId: ID) { 8 | const relations = useRecoilValue(relationsState(appId)); 9 | const getParentUuid = useCallback( 10 | (uuid: string) => { 11 | const uuids: string[] = []; 12 | for(const relation of relations){ 13 | if(relation.sourceId === uuid && 14 | relation.relationType === RelationType.INHERIT){ 15 | uuids.push(relation.targetId) 16 | } 17 | } 18 | return uuids 19 | }, 20 | [relations] 21 | ); 22 | 23 | return getParentUuid; 24 | } 25 | -------------------------------------------------------------------------------- /studio/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 12 | monospace; 13 | } 14 | .x6-widget-transform { 15 | margin: -1px 0 0 -1px; 16 | padding: 0px; 17 | border: 1px solid #239edd; 18 | } 19 | .x6-widget-transform > div { 20 | border: 1px solid #239edd; 21 | } 22 | .x6-widget-transform > div:hover { 23 | background-color: #3dafe4; 24 | } 25 | .x6-widget-transform-active-handle { 26 | background-color: #3dafe4; 27 | } 28 | .x6-widget-transform-resize { 29 | border-radius: 0; 30 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useCreateClassInnerId.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { classesState } from "../recoil/atoms"; 5 | 6 | export function useCreateClassInnerId(appId: ID) { 7 | const entities = useRecoilValue(classesState(appId)); 8 | const findEntityByInnerId = useCallback((id:number)=>{ 9 | for (const entity of entities) { 10 | if(entity.innerId === id ){ 11 | return entity 12 | } 13 | } 14 | }, [entities]) 15 | 16 | const createInnerId = useCallback((): number => { 17 | //从1001开始表id,前1000个为系统预留 18 | let index = 1001; 19 | while (findEntityByInnerId(index)) { 20 | index++; 21 | } 22 | 23 | return index; 24 | }, [findEntityByInnerId]); 25 | 26 | return createInnerId; 27 | } 28 | -------------------------------------------------------------------------------- /services/models/errorx/format.go: -------------------------------------------------------------------------------- 1 | package errorx 2 | 3 | import ( 4 | "encoding/json" 5 | 6 | "github.com/graphql-go/graphql/gqlerrors" 7 | ) 8 | 9 | func Format(err error) gqlerrors.FormattedError { 10 | errorMsg := err.Error() 11 | var code string 12 | if json.Valid([]byte(errorMsg)) { 13 | errorObj := map[string]interface{}{} 14 | json.Unmarshal([]byte(errorMsg), &errorObj) 15 | code = errorObj["code"].(string) 16 | errorMsg = errorObj["message"].(string) 17 | } 18 | 19 | if code != "" { 20 | return gqlerrors.FormattedError{ 21 | Message: errorMsg, 22 | Extensions: map[string]interface{}{ 23 | "code": code, 24 | "specifiedBy": "https://github.com/rxdrag/entix/blob/main/error-code.md", 25 | }, 26 | } 27 | } else { 28 | return gqlerrors.FormattedError{ 29 | Message: errorMsg, 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useChangeDiagram.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useSetRecoilState } from "recoil"; 3 | import { ID } from "shared"; 4 | import { DiagramMeta } from "../meta/DiagramMeta"; 5 | import { diagramsState } from "../recoil/atoms"; 6 | import { useBackupSnapshot } from "./useBackupSnapshot"; 7 | 8 | export function useChangeDiagram(appId: ID) { 9 | const backupSnapshot = useBackupSnapshot(appId); 10 | const setDiagrams = useSetRecoilState(diagramsState(appId)); 11 | 12 | const changeDiagram = useCallback( 13 | (diagram: DiagramMeta) => { 14 | backupSnapshot(); 15 | 16 | setDiagrams((diagrams) => 17 | diagrams.map((dm) => (dm.uuid === diagram.uuid ? diagram : dm)) 18 | ); 19 | }, 20 | [backupSnapshot, setDiagrams] 21 | ); 22 | 23 | return changeDiagram; 24 | } 25 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/EntityTree/CodeLabel/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { memo } from "react"; 3 | import TreeNodeLabel from "common/TreeNodeLabel"; 4 | import { useParseLangMessage } from "plugin-sdk"; 5 | import CodeAction from "./CodeAction"; 6 | import { CodeMeta } from "../../meta/CodeMeta"; 7 | 8 | const CodeLabel = memo(( 9 | props: { 10 | code: CodeMeta 11 | } 12 | ) => { 13 | const { code } = props; 14 | const [name, setName] = useState(code.name); 15 | const p = useParseLangMessage(); 16 | 17 | useEffect(() => { 18 | setName(code.name) 19 | }, [code]) 20 | 21 | return ( 22 | 25 | } 26 | > 27 |
{p(name)}
28 |
29 | ) 30 | }) 31 | 32 | export default CodeLabel; -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/canStartLink.ts: -------------------------------------------------------------------------------- 1 | import { ClassMeta, StereoType } from "../meta/ClassMeta"; 2 | import { RelationType } from "../meta/RelationMeta"; 3 | 4 | export function canStartLink(lineType: RelationType, classMeta: ClassMeta) { 5 | if (classMeta.stereoType === StereoType.Service || 6 | classMeta.stereoType === StereoType.Enum || 7 | classMeta.stereoType === StereoType.ValueObject 8 | ) { 9 | return false; 10 | } else if (lineType === RelationType.INHERIT) { 11 | if (classMeta.stereoType === StereoType.Entity || 12 | classMeta.stereoType === StereoType.Abstract 13 | ) { 14 | return true; 15 | } 16 | }else { 17 | if(classMeta.stereoType === StereoType.Abstract){ 18 | return true; 19 | } 20 | if(classMeta.stereoType === StereoType.Entity){ 21 | return true; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useChangeRelation.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useSetRecoilState } from "recoil"; 3 | import { ID } from "shared"; 4 | import { RelationMeta } from "../meta/RelationMeta"; 5 | import { relationsState } from "../recoil/atoms"; 6 | import { useBackupSnapshot } from "./useBackupSnapshot"; 7 | 8 | export function useChangeRelation(appId: ID) { 9 | const backupSnapshot = useBackupSnapshot(appId); 10 | const setRelations = useSetRecoilState(relationsState(appId)); 11 | 12 | const changeRelation = useCallback( 13 | (relation: RelationMeta) => { 14 | backupSnapshot(); 15 | 16 | setRelations((relations) => 17 | relations.map((rel) => (rel.uuid === relation.uuid ? relation : rel)) 18 | ); 19 | }, 20 | [backupSnapshot, setRelations] 21 | ); 22 | 23 | return changeRelation; 24 | } 25 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useCreateRelationInnerId.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { relationsState } from "../recoil/atoms"; 5 | 6 | export function useCreateRelationInnerId(appid: ID) { 7 | const relations = useRecoilValue(relationsState(appid)); 8 | const findRelationByInnerId = useCallback((id:number)=>{ 9 | for (const relation of relations) { 10 | if(relation.innerId === id ){ 11 | return relation 12 | } 13 | } 14 | }, [relations]) 15 | 16 | const createInnerId = useCallback((): number => { 17 | //从1001开始表id,前1000个为系统预留 18 | let index = 1001; 19 | while (findRelationByInnerId(index)) { 20 | index++; 21 | } 22 | 23 | return index; 24 | }, [findRelationByInnerId]); 25 | 26 | return createInnerId; 27 | } 28 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useUpsertClassAuthConfig.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useEdittingAppId } from "designer/hooks/useEdittingAppUuid"; 3 | import { IPostOptions, usePostOne } from "enthooks/hooks/usePostOne"; 4 | import { IClassAuthConfig, IClassAuthConfigInput } from "model"; 5 | 6 | export function useUpsertClassAuthConfig(options?: IPostOptions): [ 7 | (config: IClassAuthConfigInput) => void, 8 | { loading?: boolean; error?: Error } 9 | ] { 10 | const appId = useEdittingAppId() 11 | const [post, { error, loading }] = usePostOne("ClassAuthConfig", 12 | options 13 | ) 14 | 15 | const upsert = useCallback((config: IClassAuthConfigInput) => { 16 | post({ ...config, app: { sync: { id: appId } } }) 17 | }, [post, appId]); 18 | 19 | 20 | return [upsert, { error, loading }] 21 | } -------------------------------------------------------------------------------- /studio/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react-jsx", 22 | // "paths": { 23 | // "~/*": ["src/*"], 24 | // "plugin-sdk/*": ["src/plugin-sdk/*"], 25 | // "plugin-sdk": ["src/plugin-sdk"] 26 | // }, 27 | "baseUrl": "src" 28 | }, 29 | "include": [ 30 | "src", 31 | "craco.config.js" 32 | ] 33 | } -------------------------------------------------------------------------------- /federation/products/server.go: -------------------------------------------------------------------------------- 1 | //go:generate go run -mod=mod github.com/99designs/gqlgen 2 | package main 3 | 4 | import ( 5 | "log" 6 | "net/http" 7 | "os" 8 | 9 | "github.com/99designs/gqlgen/graphql/playground" 10 | 11 | "github.com/wundergraph/graphql-go-tools/examples/federation/products/graph" 12 | ) 13 | 14 | const defaultPort = "4002" 15 | 16 | func main() { 17 | port := os.Getenv("PORT") 18 | if port == "" { 19 | port = defaultPort 20 | } 21 | 22 | http.Handle("/", playground.Handler("GraphQL playground", "/query")) 23 | http.Handle("/query", graph.GraphQLEndpointHandler(graph.EndpointOptions{EnableDebug: true, EnableRandomness: true})) 24 | http.HandleFunc("/websocket_connections", graph.WebsocketConnectionsHandler) 25 | 26 | log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) 27 | log.Fatal(http.ListenAndServe(":"+port, nil)) 28 | } 29 | -------------------------------------------------------------------------------- /studio/src/datasource/hooks/getChildEntities.ts: -------------------------------------------------------------------------------- 1 | import { ClassMeta, RelationMeta, RelationType, StereoType } from "designer/AppUml/meta"; 2 | 3 | 4 | export const getChildEntities = (classUuid: string, classMetas: ClassMeta[], relations: RelationMeta[]) => { 5 | const classes: ClassMeta[] = []; 6 | for (const relation of relations) { 7 | if (relation.relationType === RelationType.INHERIT) { 8 | if (relation.targetId === classUuid) { 9 | const child = classMetas.find(cls => cls.uuid === relation.sourceId); 10 | if (child) { 11 | if (child.stereoType === StereoType.Entity) { 12 | classes.push(child); 13 | } 14 | const childrenOfChild = getChildEntities(child.uuid, classMetas, relations); 15 | classes.push(...childrenOfChild); 16 | } 17 | } 18 | } 19 | } 20 | return classes; 21 | }; 22 | -------------------------------------------------------------------------------- /studio/src/common/ModelBoard/PropertyBox/index.tsx: -------------------------------------------------------------------------------- 1 | import { Empty } from "antd"; 2 | import React, { memo } from "react"; 3 | import ToolbarArea from "./ToolbarArea"; 4 | import ToolbarTitle from "./ToolbarTitle"; 5 | 6 | export const PropertyBox = memo(( 7 | props: { 8 | title?: string, 9 | children?: React.ReactNode, 10 | } 11 | ) => { 12 | const { title, children } = props; 13 | return ( 14 |
17 | 18 | {title} 19 | 20 |
26 | { 27 | children ||
28 | 29 |
30 | } 31 |
32 |
33 | ); 34 | }); 35 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useQueryRoles.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "enthooks"; 2 | import { useEffect, useMemo } from "react"; 3 | import { useSetRecoilState } from "recoil"; 4 | import { useQuery } from "enthooks/hooks/useQuery"; 5 | import { IRole } from "model"; 6 | import { authRolesState } from "../recoil/atoms"; 7 | 8 | const rolesGql = gql` 9 | query { 10 | roles{ 11 | nodes{ 12 | id 13 | name 14 | } 15 | } 16 | } 17 | ` 18 | 19 | export function useQueryRoles() { 20 | const args = useMemo(() => { 21 | return { 22 | gql: rolesGql, 23 | depEntityNames: ["Role"] 24 | } 25 | }, []) 26 | const setRoles = useSetRecoilState(authRolesState); 27 | const { data, error, loading } = useQuery(args) 28 | 29 | useEffect(() => { 30 | setRoles(data?.roles?.nodes || []) 31 | }, [setRoles, data]) 32 | return { error, loading } 33 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/PropertyPanel/MethodPanel/MethodTypeInput.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Form } from "antd"; 3 | import { memo } from "react"; 4 | import { useTranslation } from "react-i18next"; 5 | import { MethodMeta } from "../../meta/MethodMeta"; 6 | import { TypeSelect } from "../TypeSelect"; 7 | import { TypeUuidSelect } from "../TypeUuidSelect"; 8 | 9 | export const MethodTypeInput = memo( 10 | ( 11 | props: { 12 | method: MethodMeta 13 | } 14 | ) => { 15 | const { method } = props; 16 | const { t } = useTranslation(); 17 | 18 | return ( 19 | <> 20 | 24 | 25 | 26 | 27 | 28 | ); 29 | } 30 | ); 31 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useExportModelJson.ts: -------------------------------------------------------------------------------- 1 | import { message } from "antd"; 2 | import { useCallback } from "react"; 3 | import { useTranslation } from "react-i18next"; 4 | import { MetaContent } from "../meta"; 5 | import { saveFile } from "./helper/saveFile"; 6 | import { useGetMeta } from "./useGetMeta"; 7 | 8 | export function useExportModelJson(appId: string) { 9 | const { t } = useTranslation(); 10 | const getMeta = useGetMeta(appId) 11 | const doExport = useCallback(() => { 12 | 13 | const data: MetaContent = getMeta(); 14 | delete data.codes; 15 | delete data.orchestrations; 16 | saveFile(appId + '-model', JSON.stringify(data, null, 2)).then( 17 | (savedName) => { 18 | if (savedName) { 19 | message.success(t("OperateSuccess")) 20 | } 21 | } 22 | ); 23 | }, [appId, getMeta, t]); 24 | 25 | return doExport 26 | } -------------------------------------------------------------------------------- /studio/src/enthooks/hooks/useInstall.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "enthooks"; 2 | import { useCallback } from "react"; 3 | import { RequestOptions, useLazyRequest } from "./useLazyRequest"; 4 | 5 | export interface InstallInput { 6 | admin: string; 7 | password: string; 8 | withDemo: boolean; 9 | meta: any; 10 | } 11 | 12 | const installMutation = gql` 13 | mutation install($input: InstallInput!) { 14 | install(input: $input) 15 | } 16 | `; 17 | 18 | export function useInstall(options?: RequestOptions): [ 19 | (input: InstallInput) => void, 20 | { 21 | error?: Error, 22 | loading?: boolean, 23 | } 24 | ] { 25 | const [doInstall, { error, loading }] = useLazyRequest(options) 26 | 27 | const install = useCallback((input: InstallInput) => { 28 | doInstall(installMutation, { input }) 29 | }, [doInstall]); 30 | 31 | return [install, { error, loading }]; 32 | } -------------------------------------------------------------------------------- /studio/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom/client'; 3 | import './index.css'; 4 | import App from './App'; 5 | import reportWebVitals from './reportWebVitals'; 6 | import { RecoilRoot } from 'recoil'; 7 | import { BrowserRouter } from 'react-router-dom'; 8 | import './i18n'; 9 | 10 | const root = ReactDOM.createRoot( 11 | document.getElementById('root') as HTMLElement 12 | ); 13 | root.render( 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ); 22 | 23 | // If you want to start measuring performance in your app, pass a function 24 | // to log results (for example: reportWebVitals(console.log)) 25 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 26 | reportWebVitals(); 27 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useUpsertPropertyAuthConfig.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useEdittingAppId } from "designer/hooks/useEdittingAppUuid"; 3 | import { IPostOptions, usePostOne } from "enthooks/hooks/usePostOne"; 4 | import { IPropertyAuthConfig, IPropertyAuthConfigInput } from "model"; 5 | 6 | export function useUpsertPropertyAuthConfig(options?: IPostOptions): [ 7 | (config: IPropertyAuthConfigInput) => void, 8 | { loading?: boolean; error?: Error } 9 | ] { 10 | const appId = useEdittingAppId() 11 | const [post, { error, loading }] = usePostOne("PropertyAuthConfig", 12 | options 13 | ) 14 | 15 | const upsert = useCallback((config: IPropertyAuthConfigInput) => { 16 | post({ ...config, app: { sync: { id: appId } } }) 17 | }, [post, appId]); 18 | 19 | 20 | return [upsert, { error, loading }] 21 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/elements/useLane.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { useMemo } from "react"; 3 | import { useTranslation } from "react-i18next"; 4 | import { useParseLangMessage } from "plugin-sdk"; 5 | import { IElement } from "./IElement"; 6 | import { useElementName } from "./useElementName"; 7 | 8 | export function useLane(element: any, modeler: any): IElement { 9 | const { t } = useTranslation(); 10 | const p = useParseLangMessage(); 11 | const name = useElementName(element, modeler); 12 | const iElement: IElement = useMemo(() => { 13 | return { 14 | type: t("AppBpmn.Group"), 15 | name: p(name), 16 | icon: , 17 | } 18 | }, [name, p, t]); 19 | 20 | return iElement; 21 | } -------------------------------------------------------------------------------- /studio/src/designer/hooks/useQueryAppConfig.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "../../enthooks"; 2 | import { useMemo } from "react"; 3 | import { SYSTEM_APP_ID } from "../../consts"; 4 | import { useQueryOne } from "../../enthooks/hooks/useQueryOne"; 5 | import { IAppConfig } from "../../model"; 6 | import { ID } from "shared"; 7 | 8 | const configGql = gql` 9 | query ($appId:ID){ 10 | oneAppConfig(where:{ 11 | app:{ 12 | id:{ 13 | _eq:$appId 14 | } 15 | } 16 | }){ 17 | id 18 | schemaJson 19 | } 20 | } 21 | ` 22 | 23 | export function useQueryAppConfig(appId: ID) { 24 | const input = useMemo(() => ({ 25 | gql: configGql, 26 | params: { appId: appId || SYSTEM_APP_ID }, 27 | depEntityNames: ["AppConfig"] 28 | }), [appId]) 29 | 30 | const { data, error, loading } = useQueryOne(input) 31 | return { config: data?.oneAppConfig, error, loading } 32 | } -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useUpsertComponentAuthConfig.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useEdittingAppId } from "designer/hooks/useEdittingAppUuid"; 3 | import { IPostOptions, usePostOne } from "enthooks/hooks/usePostOne"; 4 | import { IComponentAuthConfig, IComponentAuthConfigIput } from "model"; 5 | 6 | export function useUpsertComponentAuthConfig(options?: IPostOptions): [ 7 | (config: IComponentAuthConfigIput) => void, 8 | { loading?: boolean; error?: Error } 9 | ] { 10 | const appId = useEdittingAppId() 11 | const [post, { error, loading }] = usePostOne("ComponentAuthConfig", 12 | options 13 | ) 14 | 15 | const upsert = useCallback((config: IComponentAuthConfigIput) => { 16 | post({ ...config, app: { sync: { id: appId } } }) 17 | }, [post, appId]); 18 | 19 | 20 | return [upsert, { error, loading }] 21 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/GraphCanvas/events/index.ts: -------------------------------------------------------------------------------- 1 | export const EVENT_ELEMENT_SELECTED_CHANGE = "elementSelectedChange"; 2 | export const EVENT_PREPARE_LINK_TO = "prepareLinkTo"; 3 | export const EVENT_PRESSED_LINE_TYPE = "pressedLineType"; 4 | export const EVENT_CLASS_CHANGED = "classChanged"; 5 | export const EVENT_UNDO_REDO = "undoRedo"; 6 | 7 | export interface ICanvasEvent { 8 | name: string; 9 | detail?: any; 10 | } 11 | 12 | export function onCanvasEvent(name: string, listener: EventListener) { 13 | document.addEventListener(name, listener); 14 | } 15 | 16 | export function offCanvasEvent(name: string, listener: EventListener) { 17 | document.removeEventListener(name, listener); 18 | } 19 | 20 | export function triggerCanvasEvent(canvasEvent: ICanvasEvent) { 21 | const event = new CustomEvent(canvasEvent.name, { detail: canvasEvent.detail }); 22 | document.dispatchEvent(event); 23 | } 24 | -------------------------------------------------------------------------------- /services/models/modules/app/system-app.go: -------------------------------------------------------------------------------- 1 | package app 2 | 3 | import ( 4 | "github.com/codebdy/entify-core" 5 | "github.com/codebdy/entify-graphql-schema/schema" 6 | "github.com/codebdy/leda-service-sdk/config" 7 | "github.com/codebdy/leda-service-sdk/system" 8 | ) 9 | 10 | var sysApp *App 11 | 12 | func GetSystemApp() *App { 13 | if sysApp == nil { 14 | sysApp = createPredefinedSystemApp() 15 | } 16 | 17 | return sysApp 18 | } 19 | 20 | func ReloadSystemApp() *App { 21 | sysApp = createPredefinedSystemApp() 22 | return sysApp 23 | } 24 | 25 | func createPredefinedSystemApp() *App { 26 | metaConent := *system.SystemMeta 27 | //mergedMetaConent := MergeServiceModels(&metaConent) 28 | repo := entify.New(config.GetDbConfig()) 29 | repo.Init(metaConent, 0) 30 | schema := schema.New(repo) 31 | return &App{ 32 | Schema: schema, 33 | //Parser: schema.Parser(), 34 | Repo: repo, 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /studio/src/designer/hooks/useQueryApp.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "../../enthooks"; 2 | import { useMemo } from "react"; 3 | import { SYSTEM_APP_ID } from "../../consts"; 4 | import { useQueryOne } from "../../enthooks/hooks/useQueryOne"; 5 | import { IApp } from "../../model"; 6 | import { ID } from "shared"; 7 | 8 | const appGql = gql` 9 | query ($appId:ID!){ 10 | oneApp(where:{ 11 | id:{ 12 | _eq:$appId 13 | } 14 | }){ 15 | id 16 | uuid 17 | title 18 | saveMetaAt 19 | publishMetaAt 20 | } 21 | } 22 | ` 23 | 24 | export function useQueryApp(id: ID) { 25 | const params = useMemo(() => ({ 26 | appId: id || SYSTEM_APP_ID 27 | }), [id]) 28 | 29 | const { data, error, loading } = useQueryOne( 30 | { 31 | gql: appGql, 32 | params, 33 | depEntityNames: ["App"], 34 | } 35 | 36 | ) 37 | 38 | return { app: data?.oneApp, error, loading } 39 | } -------------------------------------------------------------------------------- /studio/src/plugins/framelayouts/pc/Container/view/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { CSSProperties, memo } from "react" 2 | import cls from "classnames" 3 | import "./style.less" 4 | 5 | export interface IComponentProps { 6 | className?: string, 7 | maxWidth?: "xs" | "sm" | "md" | "lg" | "xl" | "xxl" | false, 8 | children?: React.ReactNode, 9 | style?: CSSProperties, 10 | } 11 | 12 | const Component = memo((props: IComponentProps) => { 13 | const { className, maxWidth="xl", ...other } = props 14 | let maxWidthClass = ""; 15 | if (maxWidth === "xs" || 16 | maxWidth === "sm" || 17 | maxWidth === "md" || 18 | maxWidth === "lg" || 19 | maxWidth === "xl" || 20 | maxWidth === "xxl") { 21 | maxWidthClass = "max-" + maxWidth; 22 | } 23 | 24 | return ( 25 |
26 | ) 27 | }) 28 | 29 | export default Component; -------------------------------------------------------------------------------- /studio/src/common/ListConentLayout/index.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { memo } from "react" 3 | import { ResizableColumn } from "../ResizableColumn"; 4 | import "./style.less" 5 | import cls from "classnames" 6 | 7 | export const ListConentLayout = memo(( 8 | props: { 9 | listWidth?: number, 10 | list?: React.ReactNode, 11 | children?: React.ReactNode, 12 | className?: string, 13 | } 14 | ) => { 15 | const { listWidth, list, children, className } = props; 16 | return ( 17 |
18 | 19 | {list} 20 | 21 |
28 | {children} 29 |
30 |
31 | ) 32 | }) -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/elements/useElementName.ts: -------------------------------------------------------------------------------- 1 | import { useCallback, useEffect, useState } from "react"; 2 | 3 | export function useElementName(element: any, modeler: any): string { 4 | const [name, setName] = useState(""); 5 | 6 | useEffect(() => { 7 | setName(element?.businessObject?.name || "") 8 | }, [element]) 9 | 10 | const handleElementChanged = useCallback((e:any) => { 11 | if (element?.businessObject && element?.businessObject?.id === e.element?.businessObject?.id) { 12 | setName(e.element?.businessObject?.name) 13 | } 14 | }, [element]) 15 | 16 | useEffect(() => { 17 | //console.log("eventBus事件列表", modeler?.get('eventBus')) 18 | modeler?.on('element.changed', handleElementChanged); 19 | return () => { 20 | modeler?.off('element.changed', handleElementChanged) 21 | } 22 | }, [modeler, handleElementChanged]) 23 | 24 | return name; 25 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useDeleteMethod.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { classesState } from "../recoil/atoms"; 5 | import { useChangeClass } from "./useChangeClass"; 6 | 7 | export function useDeleteMethod(appId: ID) { 8 | const changeClass = useChangeClass(appId); 9 | const clses = useRecoilValue(classesState(appId)) 10 | 11 | const deleteMethod = useCallback( 12 | (methodUuid: string) => { 13 | for(const cls of clses){ 14 | if(cls.methods.find((mthd) => mthd.uuid === methodUuid)){ 15 | changeClass({ 16 | ...cls, 17 | methods: cls.methods.filter( 18 | (mth) => mth.uuid !== methodUuid 19 | ), 20 | }) 21 | } 22 | } 23 | }, 24 | [changeClass, clses] 25 | ); 26 | 27 | return deleteMethod; 28 | } 29 | -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/elements/useParticipant.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | import { useParseLangMessage } from "plugin-sdk"; 4 | import { IElement } from "./IElement"; 5 | import { useElementName } from "./useElementName"; 6 | 7 | export function useParticipant(element: any, modeler: any): IElement { 8 | const { t } = useTranslation(); 9 | const p = useParseLangMessage(); 10 | const name = useElementName(element, modeler); 11 | const iElement: IElement = useMemo(() => { 12 | return { 13 | type: t("AppBpmn.Participant"), 14 | name: p(name), 15 | icon: , 16 | } 17 | }, [name, p, t]); 18 | 19 | return iElement; 20 | } -------------------------------------------------------------------------------- /studio/src/enthooks/events/index.ts: -------------------------------------------------------------------------------- 1 | import { IPosted } from "./IPosted"; 2 | import { IRemoved } from "./IRemoved"; 3 | import { IUpdated } from "./IUpdated"; 4 | 5 | export const EVENT_DATA_POSTED = "appx:posted"; 6 | export const EVENT_DATA_REMOVED = "appx:removed"; 7 | export const EVENT_DATA_UPDATED = "appx:updated"; 8 | 9 | export type Handler = (event: CustomEvent) => void; 10 | 11 | function on(eventType: string, listener: EventListener) { 12 | document.addEventListener(eventType, listener); 13 | } 14 | 15 | function off(eventType: string, listener: EventListener) { 16 | document.removeEventListener(eventType, listener); 17 | } 18 | 19 | function trigger(eventType: string, data: IPosted | IRemoved | IUpdated) { 20 | console.log('trigger事件', eventType, data); 21 | const event = new CustomEvent(eventType, { detail: data }); 22 | document.dispatchEvent(event); 23 | } 24 | 25 | export { on, off, trigger }; 26 | -------------------------------------------------------------------------------- /studio/src/model/page.ts: -------------------------------------------------------------------------------- 1 | import { Device } from "@rxdrag/appx-plugin-sdk"; 2 | import { ID } from "shared"; 3 | import { IApp, IAppInput } from "./app"; 4 | 5 | export interface IPageCategory { 6 | id: ID; 7 | title?: string; 8 | device?: Device; 9 | app?: IApp; 10 | uuid: string; 11 | } 12 | 13 | 14 | export interface IPage { 15 | id: ID; 16 | title: string; 17 | schemaJson: { form: any, schema: any/* ISchema */ }; 18 | device: Device; 19 | app?: IApp; 20 | categoryUuid?: string; 21 | uuid: string; 22 | } 23 | 24 | export interface IPageCategoryInput { 25 | id?: ID; 26 | title?: string; 27 | device?: Device; 28 | app?: { sync: IAppInput }; 29 | uuid?: string; 30 | } 31 | 32 | export interface IPageInput { 33 | id?: ID; 34 | title?: string; 35 | schemaJson?: any; 36 | device?: Device; 37 | app?: { sync: IAppInput }; 38 | categoryUuid?: string; 39 | uuid?: string; 40 | } 41 | -------------------------------------------------------------------------------- /studio/src/consts.ts: -------------------------------------------------------------------------------- 1 | export const SERVER_URL = "http://localhost:4000/graphql" 2 | 3 | export const PRIMARY_COLOR = "#5d78ff"; 4 | export const SERVER_SUBSCRIPTION_URL = "ws://localhost:4000/subscriptions"; 5 | //export const UPLOAD_SERVER = "http://localhost:4000"; 6 | 7 | export const HEADER_AUTHORIZATION = "Authorization" 8 | export const TOKEN_PREFIX= "Bearer " 9 | export const HEADER_APPX_APPID ="Appx-appid" 10 | export const DESIGNER_TOKEN_NAME = "EntifyDesignerToken"; 11 | 12 | //普通角色的ID永远不会是1 13 | export const GUEST_ROLE_ID = "1" 14 | 15 | export const LOGIN_URL = "/login" 16 | export const INSTALL_URL = "/install" 17 | export const INDEX_URL = "/" 18 | export const DESIGN = "design" 19 | export const DESIGN_UI = "design-ui" 20 | export const DESIGN_FRAME = "design-frame" 21 | export const DESIGN_BOARD = "design-board" 22 | 23 | export const SYSTEM_APP_ID = "1" 24 | 25 | export const CODE_LOGIN_EXPIRED = "entix.0001" 26 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useQueryAppMenus.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "enthooks"; 2 | import { useMemo } from "react"; 3 | import { useQuery } from "enthooks/hooks/useQuery"; 4 | import { useEdittingAppId } from "designer/hooks/useEdittingAppUuid"; 5 | import { IMenu } from "model"; 6 | 7 | const menuGql = gql` 8 | query ($appId:ID!){ 9 | menus(where:{ 10 | app:{ 11 | id:{ 12 | _eq:$appId 13 | } 14 | } 15 | } 16 | ){ 17 | nodes{ 18 | id 19 | device 20 | schemaJson 21 | } 22 | } 23 | } 24 | ` 25 | 26 | export function useQueryAppMenus() { 27 | const appId = useEdittingAppId(); 28 | 29 | const input = useMemo(() => ({ 30 | gql: menuGql, 31 | params: { appId }, 32 | depEntityNames: ["Menu"] 33 | }), [appId]); 34 | 35 | const { data, error, loading } = useQuery(input) 36 | 37 | return { menus: data?.menus?.nodes, error, loading } 38 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useUpsertProcess.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { IPostOptions, usePostOne } from "enthooks/hooks/usePostOne"; 3 | import { IProcessInput, IProcess } from "model/process"; 4 | import { useDesignerParams } from "plugin-sdk/contexts/desinger"; 5 | 6 | export function useUpsertProcess(options?: IPostOptions): [ 7 | (page: IProcessInput) => void, 8 | { loading?: boolean; error?: Error } 9 | ] { 10 | const params = useDesignerParams(); 11 | 12 | const [post, { error, loading }] = usePostOne("Process", 13 | { 14 | ...options, 15 | } 16 | ) 17 | 18 | const upsert = useCallback((page: IProcessInput) => { 19 | post({ 20 | ...page, 21 | app: { 22 | sync: { id: params.app.id } 23 | }, 24 | }) 25 | }, [params.app.id, post]); 26 | 27 | 28 | return [upsert, { error: error, loading: loading }] 29 | } -------------------------------------------------------------------------------- /studio/src/designer/hooks/useQueryLangLocales.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "../../enthooks"; 2 | import { useMemo } from "react"; 3 | import { SYSTEM_APP_ID } from "../../consts"; 4 | import { useQuery } from "../../enthooks/hooks/useQuery"; 5 | import { ILangLocal } from "../../model"; 6 | 7 | const langLocalGql = gql` 8 | query ($appId:ID!){ 9 | langLocals(where:{ 10 | app:{ 11 | id:{ 12 | _eq:$appId 13 | } 14 | } 15 | }){ 16 | nodes{ 17 | id 18 | name 19 | schemaJson 20 | } 21 | } 22 | } 23 | ` 24 | 25 | export function useQueryLangLocales(appId: string) { 26 | const input = useMemo(() => ({ 27 | gql: langLocalGql, 28 | params: { appId: appId || SYSTEM_APP_ID }, 29 | depEntityNames: ["LangLocal"] 30 | }), [appId]) 31 | const { data, error, loading } = useQuery(input) 32 | return { langLocales: data?.langLocals?.nodes, error, loading } 33 | } -------------------------------------------------------------------------------- /gateway/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/nautilus/gateway/cmd/gateway 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/codebdy/leda-service-sdk v0.0.4 7 | github.com/nautilus/gateway v0.3.9 8 | github.com/nautilus/graphql v0.0.20 9 | github.com/spf13/cobra v0.0.5 10 | ) 11 | 12 | require ( 13 | github.com/99designs/gqlgen v0.17.15 // indirect 14 | github.com/agnivade/levenshtein v1.1.1 // indirect 15 | github.com/graph-gophers/dataloader v5.0.0+incompatible // indirect 16 | github.com/inconshreveable/mousetrap v1.0.0 // indirect 17 | github.com/mitchellh/mapstructure v1.5.0 // indirect 18 | github.com/opentracing/opentracing-go v1.2.0 // indirect 19 | github.com/sirupsen/logrus v1.9.0 // indirect 20 | github.com/spf13/pflag v1.0.5 // indirect 21 | github.com/vektah/gqlparser/v2 v2.4.8 // indirect 22 | golang.org/x/sys v0.7.0 // indirect 23 | ) 24 | 25 | //replace github.com/codebdy/leda-service-sdk v0.0.3 => ../../leda-service-sdk 26 | -------------------------------------------------------------------------------- /studio/src/common/ModelBoard/style.less: -------------------------------------------------------------------------------- 1 | @import "../../variables.less"; 2 | 3 | .appx-model-board{ 4 | flex: 1; 5 | display: flex; 6 | flex-flow: row; 7 | height: calc(100vh - @toolbarHeight); 8 | background-color: @canvasBackgroundColor; 9 | .model-tree-shell{ 10 | display: flex; 11 | flex-flow: column; 12 | background-color: @backgrounColor; 13 | border-right: solid 1px @borderColor; 14 | width: 100%; 15 | height: 100%; 16 | overflow: auto; 17 | } 18 | .property-box-area{ 19 | display: flex; 20 | height: 100%; 21 | flex-flow: column; 22 | width: 260px; 23 | background-color: @backgrounColor; 24 | .property-box{ 25 | flex:1; 26 | display: flex; 27 | flex-flow: column; 28 | height: 0; 29 | overflow: auto; 30 | width: 100%; 31 | .property-pannel{ 32 | padding: 8px 16px; 33 | } 34 | } 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useExportOrchestrationJson.ts: -------------------------------------------------------------------------------- 1 | import { message } from "antd"; 2 | import { useCallback } from "react"; 3 | import { useTranslation } from "react-i18next"; 4 | import { MetaContent } from "../meta"; 5 | import { saveFile } from "./helper/saveFile"; 6 | import { useGetMeta } from "./useGetMeta"; 7 | 8 | export function useExportOrchestrationJson(appId: string) { 9 | const { t } = useTranslation(); 10 | const getMeta = useGetMeta(appId) 11 | const doExport = useCallback(() => { 12 | 13 | const data: MetaContent = getMeta(); 14 | saveFile(appId + '-orchestration', JSON.stringify({ 15 | codes: data.codes, 16 | orchestrations: data.orchestrations, 17 | }, null, 2)).then( 18 | (savedName) => { 19 | if (savedName) { 20 | message.success(t("OperateSuccess")) 21 | } 22 | } 23 | ); 24 | }, [appId, getMeta, t]); 25 | 26 | return doExport 27 | } -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useUpsertMenuAuthConfig.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useEdittingAppId } from "designer/hooks/useEdittingAppUuid"; 3 | import { IPostOptions, usePostOne } from "enthooks/hooks/usePostOne"; 4 | import { IMenuAuthConfig, IMenuAuthConfigInput } from "model"; 5 | import { GraphQLRequestError } from "enthooks"; 6 | 7 | export function useUpsertMenuAuthConfig(options?: IPostOptions): [ 8 | (config: IMenuAuthConfigInput) => void, 9 | { loading?: boolean; error?: GraphQLRequestError | Error } 10 | ] { 11 | const appId = useEdittingAppId() 12 | const [post, { error, loading }] = usePostOne("MenuAuthConfig", 13 | options 14 | ) 15 | 16 | const upsert = useCallback((config: IMenuAuthConfigInput) => { 17 | post({ ...config, app: { sync: { id: appId } } }) 18 | }, [post, appId]); 19 | 20 | 21 | return [upsert, { error, loading }] 22 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/PropertyPanel/elements/useCollaboration.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | import { useTranslation } from "react-i18next"; 3 | import { IElement } from "./IElement"; 4 | 5 | export function useCollaboration(element: any, modeler: any): IElement { 6 | const { t } = useTranslation(); 7 | const iElement: IElement = useMemo(() => { 8 | return { 9 | type: t("AppBpmn.Collaboration"), 10 | name: false, 11 | icon: , 12 | } 13 | }, [t]); 14 | 15 | return iElement; 16 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useDeleteAttribute.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useRecoilValue } from "recoil"; 3 | import { ID } from "shared"; 4 | import { classesState } from "../recoil/atoms"; 5 | import { useChangeClass } from "./useChangeClass"; 6 | 7 | export function useDeleteAttribute(appId: ID) { 8 | const changeClass = useChangeClass(appId); 9 | const clses = useRecoilValue(classesState(appId)) 10 | 11 | const deleteAttribute = useCallback( 12 | (attributeUuid: string) => { 13 | for(const cls of clses){ 14 | if(cls.attributes.find((attr) => attr.uuid === attributeUuid)){ 15 | changeClass({ 16 | ...cls, 17 | attributes: cls.attributes.filter( 18 | (atr) => atr.uuid !== attributeUuid 19 | ), 20 | }) 21 | } 22 | } 23 | }, 24 | [changeClass, clses] 25 | ); 26 | 27 | return deleteAttribute; 28 | } 29 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useDeleteRelation.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { useSetRecoilState } from "recoil"; 3 | import { ID } from "shared"; 4 | import { relationsState, x6EdgesState } from "../recoil/atoms"; 5 | import { useBackupSnapshot } from "./useBackupSnapshot"; 6 | 7 | export function useDeleteRelation(appId: ID) { 8 | const setRelation = useSetRecoilState(relationsState(appId)); 9 | const setEdges = useSetRecoilState(x6EdgesState(appId)); 10 | 11 | const backupSnapshot = useBackupSnapshot(appId); 12 | 13 | const deleteRelation = useCallback( 14 | (uuid: string) => { 15 | backupSnapshot(); 16 | setRelation((relations) => 17 | relations.filter((relation) => relation.uuid !== uuid) 18 | ); 19 | setEdges((edges) => edges.filter((edge) => edge.id !== uuid)); 20 | }, 21 | [backupSnapshot, setEdges, setRelation] 22 | ); 23 | 24 | return deleteRelation; 25 | } 26 | -------------------------------------------------------------------------------- /studio/src/Install/Installed.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "antd" 2 | import React, { memo, useCallback } from "react" 3 | import { useTranslation } from "react-i18next" 4 | import { useNavigate } from "react-router-dom" 5 | import { LOGIN_URL } from "../consts" 6 | 7 | const Installed = memo(() => { 8 | const { t } = useTranslation(); 9 | const navigate = useNavigate() 10 | const handleLogin = useCallback(() => { 11 | navigate(LOGIN_URL) 12 | }, [navigate]) 13 | return ( 14 |
19 |
20 | {t("Install.InstalledMessage")} 21 |
22 |
23 | 26 |
27 |
28 | ) 29 | }) 30 | 31 | export default Installed -------------------------------------------------------------------------------- /studio/src/designer/AppUml/PropertyPanel/MethodPanel/ArgsInput/LazyInput.tsx: -------------------------------------------------------------------------------- 1 | import { Input, InputProps } from "antd" 2 | import React, { useCallback, useEffect, useState } from "react" 3 | import { memo } from "react" 4 | 5 | export const LazyInput = memo(( 6 | props: InputProps & { 7 | value?: string, 8 | onChange: (value?: string) => void, 9 | } 10 | ) => { 11 | const { value, onChange, ...other } = props; 12 | const [inputValue, setInputValue] = useState(""); 13 | 14 | useEffect(() => { 15 | setInputValue(value as any); 16 | }, [value]) 17 | 18 | const handleChange = useCallback((e: React.ChangeEvent) => { 19 | setInputValue(e.target.value) 20 | }, []) 21 | 22 | 23 | const handleBlur = useCallback(() => { 24 | onChange(inputValue) 25 | }, [inputValue, onChange]); 26 | 27 | return ( 28 | 29 | ) 30 | }) -------------------------------------------------------------------------------- /studio/src/designer/AppConfig/index.tsx: -------------------------------------------------------------------------------- 1 | import { Collapse } from 'antd'; 2 | import React, { memo } from 'react'; 3 | import { useTranslation } from 'react-i18next'; 4 | import MultLangForm from './MultLangForm'; 5 | const { Panel } = Collapse; 6 | 7 | const AppConfig = memo(() => { 8 | const { t } = useTranslation(); 9 | 10 | return ( 11 |
14 |
20 | 21 | 22 | 23 | 24 | 25 |

Other config

26 |
27 |
28 |
29 |
30 | ); 31 | }); 32 | 33 | export default AppConfig; -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useGetAllParentUuids.ts: -------------------------------------------------------------------------------- 1 | import { useCallback } from "react"; 2 | import { ID } from "shared"; 3 | import { useGetFirstParentUuids } from "./useGetFirstParentUuids"; 4 | 5 | export function useGetAllParentUuids(appId: ID) { 6 | const getFirstParentId = useGetFirstParentUuids(appId); 7 | 8 | const getParentUuids = useCallback( 9 | (uuid: string) => { 10 | const parents: string[] = []; 11 | let currentUuids: string[] = [uuid]; 12 | do { 13 | const newCurrentIds: string[] = []; 14 | for (const curenttId of currentUuids) { 15 | const uuids = getFirstParentId(curenttId); 16 | newCurrentIds.push(...uuids); 17 | parents.push(...uuids); 18 | } 19 | currentUuids = newCurrentIds; 20 | } while (currentUuids.length > 0); 21 | 22 | return parents; 23 | }, 24 | [getFirstParentId] 25 | ); 26 | 27 | return getParentUuids; 28 | } 29 | -------------------------------------------------------------------------------- /studio/src/designer/hooks/useAppDevicePages.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { IApp } from "../../model"; 3 | import { gql } from "../../enthooks"; 4 | import { useQueryOne } from "../../enthooks/hooks/useQueryOne"; 5 | import { useMemo } from "react"; 6 | import { Device } from "@rxdrag/appx-plugin-sdk"; 7 | 8 | const appsGql = gql` 9 | query queryApp($device:DeviceEnumComparisonExp!, id:ID!){ 10 | oneApp(where:{ 11 | id:{ 12 | _eq:$id 13 | } 14 | }){ 15 | id 16 | title 17 | pages(where:{ 18 | device:{ 19 | _eq:$device 20 | } 21 | }){ 22 | id 23 | schema 24 | title 25 | } 26 | } 27 | } 28 | ` 29 | 30 | export function useAppDevicePages(id: ID, device: Device) { 31 | const params = useMemo(() => ({ id, device }), [device, id]); 32 | return useQueryOne( 33 | { 34 | gql: appsGql, 35 | params, 36 | depEntityNames: ["App", "Page"] 37 | }) 38 | } -------------------------------------------------------------------------------- /federation/accounts/graph/schema.resolvers.go: -------------------------------------------------------------------------------- 1 | package graph 2 | 3 | // This file will be automatically regenerated based on the schema, any resolver implementations 4 | // will be copied through when generating and any unknown code will be moved to the end. 5 | // Code generated by github.com/99designs/gqlgen version v0.17.22 6 | 7 | import ( 8 | "context" 9 | 10 | "github.com/wundergraph/graphql-go-tools/examples/federation/accounts/graph/generated" 11 | "github.com/wundergraph/graphql-go-tools/examples/federation/accounts/graph/model" 12 | ) 13 | 14 | // Me is the resolver for the me field. 15 | func (r *queryResolver) Me(ctx context.Context) (*model.User, error) { 16 | return &model.User{ 17 | ID: "1234", 18 | Username: "Me", 19 | }, nil 20 | } 21 | 22 | // Query returns generated.QueryResolver implementation. 23 | func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } 24 | 25 | type queryResolver struct{ *Resolver } 26 | -------------------------------------------------------------------------------- /studio/src/designer/AppAuth/hooks/useQueryAppPages.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "enthooks"; 2 | import { useMemo } from "react"; 3 | import { useQuery } from "enthooks/hooks/useQuery"; 4 | import { useEdittingAppId } from "designer/hooks/useEdittingAppUuid"; 5 | import { IPage } from "model"; 6 | 7 | const pagesGql = gql` 8 | query ($appId:ID!){ 9 | pages(where:{ 10 | app:{ 11 | id:{ 12 | _eq:$appId 13 | } 14 | } 15 | } 16 | ){ 17 | nodes{ 18 | id 19 | title 20 | device 21 | schemaJson 22 | categoryUuid 23 | } 24 | } 25 | } 26 | ` 27 | 28 | export function useQueryAppPages() { 29 | const appId = useEdittingAppId(); 30 | 31 | const input = useMemo(() => ({ 32 | gql: pagesGql, 33 | params: { appId }, 34 | depEntityNames: ["Page"] 35 | }), [appId]); 36 | 37 | const { data, error, loading } = useQuery(input) 38 | 39 | return { pages: data?.pages?.nodes, error, loading } 40 | } -------------------------------------------------------------------------------- /studio/src/designer/AppUml/EntityTree/OrchestrationLabel/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { memo } from "react"; 3 | import TreeNodeLabel from "common/TreeNodeLabel"; 4 | import { useParseLangMessage } from "plugin-sdk"; 5 | import { OrchestrationAction } from "./OrchestrationAction"; 6 | import { OrchestrationMeta } from "../../meta/OrchestrationMeta"; 7 | 8 | export const OrchestrationLabel = memo(( 9 | props: { 10 | orchestration: OrchestrationMeta 11 | } 12 | ) => { 13 | const { orchestration } = props; 14 | const [name, setName] = useState(orchestration.name); 15 | const p = useParseLangMessage(); 16 | 17 | useEffect(() => { 18 | setName(orchestration.name) 19 | }, [orchestration]) 20 | 21 | 22 | return ( 23 | 26 | } 27 | > 28 |
{p(name)}
29 |
30 | ) 31 | }) 32 | -------------------------------------------------------------------------------- /studio/src/designer/AppUml/hooks/useIsElement.ts: -------------------------------------------------------------------------------- 1 | import { ID } from "shared"; 2 | import { useRecoilValue } from 'recoil'; 3 | import { classesState } from "../recoil/atoms"; 4 | import { useCallback } from 'react'; 5 | 6 | export function useIsElement(appId: ID) { 7 | const classes = useRecoilValue(classesState(appId)); 8 | 9 | const isElement = useCallback((uuid: string) => { 10 | for (const cls of classes) { 11 | if (cls.uuid === uuid) { 12 | return true; 13 | } 14 | if(cls.attributes){ 15 | for (const attr of cls.attributes) { 16 | if (attr.uuid === uuid) { 17 | return true; 18 | } 19 | } 20 | } 21 | 22 | if(cls.methods){ 23 | for (const method of cls.methods) { 24 | if (method.uuid === uuid) { 25 | return true; 26 | } 27 | } 28 | } 29 | 30 | } 31 | return false 32 | }, [classes]) 33 | 34 | return isElement 35 | } -------------------------------------------------------------------------------- /studio/src/designer/AppBpmn/hooks/useQueryCagegories.ts: -------------------------------------------------------------------------------- 1 | import { gql, useQuery } from "enthooks"; 2 | import { useMemo } from "react"; 3 | import { useParams } from "react-router-dom"; 4 | import { IProcessCategory } from "model"; 5 | 6 | const categoriesGql = gql` 7 | query ($appId:ID!){ 8 | processCategories(where:{ 9 | app:{ 10 | id:{ 11 | _eq:$appId 12 | } 13 | } 14 | }, 15 | orderBy:{ 16 | id:asc 17 | } 18 | ){ 19 | nodes{ 20 | id 21 | name 22 | uuid 23 | } 24 | } 25 | } 26 | ` 27 | 28 | export function useQueryCagegories() { 29 | const { appId } = useParams(); 30 | 31 | const args = useMemo(() => { 32 | return { 33 | gql: categoriesGql, 34 | params: { appId }, 35 | depEntityNames: ["ProcessCategory"] 36 | } 37 | }, [appId]) 38 | const { data, error, loading } = useQuery(args) 39 | 40 | return { categories: data?.processCategories?.nodes, error, loading } 41 | } -------------------------------------------------------------------------------- /studio/src/model/template.ts: -------------------------------------------------------------------------------- 1 | import { Device } from "@rxdrag/appx-plugin-sdk"; 2 | import { ID } from "shared"; 3 | import { IApp, IAppInput } from "./app"; 4 | 5 | export enum CategoryType { 6 | Public = "Public", 7 | Local = "Local" 8 | } 9 | 10 | export enum TemplateType { 11 | Frame = "Frame", 12 | Page = "Page" 13 | } 14 | 15 | export interface ElementsJson { 16 | elements?: any[] 17 | } 18 | 19 | export interface ITemplateInfo { 20 | id?: ID; 21 | name?: string; 22 | imageUrl?: string; 23 | dependencies?: any; 24 | schemaJson?: ElementsJson; 25 | app?: IApp; 26 | device?: Device; 27 | categoryType?: CategoryType; 28 | templateType?: TemplateType; 29 | } 30 | 31 | export interface ITemplateInfoInput { 32 | id?: ID; 33 | name?: string; 34 | imageUrl?: string; 35 | dependencies?: any; 36 | schemaJson?: ElementsJson; 37 | app: { sync: IAppInput }; 38 | device?: Device; 39 | categoryType: CategoryType; 40 | templateType: TemplateType; 41 | } 42 | -------------------------------------------------------------------------------- /studio/src/dashboard/AppManager/AppModal/CreateAppDialog.tsx: -------------------------------------------------------------------------------- 1 | import { PlusOutlined } from '@ant-design/icons'; 2 | import { Button } from 'antd'; 3 | import React, { memo, useState } from 'react'; 4 | import { useTranslation } from 'react-i18next'; 5 | import { UpsertAppModel } from './UpsertAppModel'; 6 | 7 | export const CreateAppDialog = memo(() => { 8 | const [isModalVisible, setIsModalVisible] = useState(false); 9 | const { t } = useTranslation(); 10 | 11 | const showModal = () => { 12 | setIsModalVisible(true); 13 | }; 14 | 15 | 16 | const handleCancel = () => { 17 | setIsModalVisible(false); 18 | }; 19 | 20 | return ( 21 | <> 22 | 30 | 31 | 32 | ); 33 | }); 34 | --------------------------------------------------------------------------------