CI: Appflowy tauri ci (#1851)

* chore: add notification parser

* chore: rename classes to models

* refactor: add effects and reducers folder

* chore: update eslint version

* chore: run npx eslint --fix src

* fix: ParserOptions.project error by ignore linting the  .eslintrc.cjs

* ci: add tauri lint

* ci: disable ubuntu and windows tauri ci

* ci: install

---------

Co-authored-by: Annie <anqi.annie.wang@gmail.com>
This commit is contained in:
Nathan.fooo 2023-02-13 19:24:16 +08:00 committed by GitHub
parent 59cb4a890a
commit 51041f6860
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
65 changed files with 110 additions and 106 deletions

View File

@ -14,7 +14,8 @@ jobs:
strategy:
fail-fast: false
matrix:
platform: [macos-latest, ubuntu-20.04, windows-latest]
# platform: [macos-latest, ubuntu-20.04, windows-latest]
platform: [macos-latest]
runs-on: ${{ matrix.platform }}
steps:
@ -61,6 +62,13 @@ jobs:
cargo install --force cargo-make
cargo make appflowy-tauri-deps-tools
- name: lint
working-directory: frontend/appflowy_tauri
run: |
yarn --frozen-lockfile
yarn test:prettier
yarn test:code
- name: build
working-directory: frontend/appflowy_tauri
run: |

View File

@ -27,6 +27,8 @@
"prettier.printWidth": 140,
"editor.wordWrap": "wordWrapColumn",
"dart.lineLength": 80,
"typescript.validate.enable": true,
"javascript.validate.enable": true,
"files.associations": {
"*.log.*": "log"
},

View File

@ -170,7 +170,7 @@
"type": "shell",
"isBackground": true,
"command": "npm run dev",
"problemMatcher": ["$tsc"],
"problemMatcher": "$tsc-watch",
"options": {
"cwd": "${workspaceFolder}/appflowy_tauri"
}
@ -179,7 +179,7 @@
"label": "AF: Tauri UI Build",
"type": "shell",
"command": "npm run build",
"problemMatcher": ["$tsc"],
"problemMatcher": "$tsc-watch",
"options": {
"cwd": "${workspaceFolder}/appflowy_tauri"
}
@ -188,7 +188,7 @@
"label": "AF: Tauri Dev",
"type": "shell",
"command": "npm run tauri dev",
"problemMatcher": ["$tsc"],
"problemMatcher": "$tsc-watch",
"options": {
"cwd": "${workspaceFolder}/appflowy_tauri"
}
@ -200,7 +200,7 @@
"options": {
"cwd": "${workspaceFolder}"
},
"problemMatcher": ["$tsc"]
"problemMatcher": "$tsc-watch"
},
{
"label": "AF: Tauri Clean + Dev",
@ -213,6 +213,14 @@
"options": {
"cwd": "${workspaceFolder}"
}
}
},
{
"label": "AF: Tauri ESLint",
"type": "shell",
"command": "npx eslint --fix src",
"options": {
"cwd": "${workspaceFolder}/appflowy_tauri"
}
},
]
}

View File

@ -1,2 +1,4 @@
/src/services
/src/styles
/src/styles
.eslintrc.cjs
node_modules

View File

@ -23,5 +23,5 @@ dist-ssr
*.sln
*.sw?
**/src/services/backend/classes/
**/src/services/backend/models/
**/src/services/backend/events/

View File

@ -8,6 +8,8 @@
"build": "tsc && vite build",
"preview": "vite preview",
"format": "prettier --write .",
"test:code": "eslint --max-warnings=0 --ext .js,.ts,.tsx .",
"test:prettier": "yarn prettier --list-different src",
"tauri:dev": "tauri dev"
},
"dependencies": {
@ -29,11 +31,12 @@
"@types/node": "^18.7.10",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"@typescript-eslint/eslint-plugin": "^5.49.0",
"@typescript-eslint/parser": "^5.49.0",
"@typescript-eslint/eslint-plugin": "^5.51.0",
"@typescript-eslint/parser": "^5.51.0",
"@vitejs/plugin-react": "^3.0.0",
"autoprefixer": "^10.4.13",
"eslint": "^8.33.0",
"eslint": "^8.34.0",
"eslint-plugin-react": "^7.32.2",
"postcss": "^8.4.21",
"prettier": "^2.8.3",
"prettier-plugin-tailwindcss": "^0.2.2",

View File

@ -2,16 +2,16 @@ import { Routes, Route, BrowserRouter } from 'react-router-dom';
import { TestColors } from './components/TestColors/TestColors';
import TestApiButton from './components/TestApiButton/TestApiButton';
import { Welcome } from './pages/Welcome';
import { Welcome } from './views/Welcome';
import { Provider } from 'react-redux';
import { store } from './store';
import { DocumentPage } from './pages/DocumentPage';
import { BoardPage } from './pages/BoardPage';
import { GridPage } from './pages/GridPage';
import { LoginPage } from './pages/LoginPage';
import { store } from './stores/store';
import { DocumentPage } from './views/DocumentPage';
import { BoardPage } from './views/BoardPage';
import { GridPage } from './views/GridPage';
import { LoginPage } from './views/LoginPage';
import { ProtectedRoutes } from './components/auth/ProtectedRoutes';
import { SignUpPage } from './pages/SignUpPage';
import { ConfirmAccountPage } from './pages/ConfirmAccountPage';
import { SignUpPage } from './views/SignUpPage';
import { ConfirmAccountPage } from './views/ConfirmAccountPage';
const App = () => {
// const location = useLocation();

View File

@ -1,9 +1,6 @@
import {
UserEventSignIn,
SignInPayloadPB,
UserEventGetUserProfile,
UserEventGetUserSetting,
} from '../../../services/backend/events/flowy-user/index';
} from '../../../services/backend/models/flowy-user/index';
import { nanoid } from 'nanoid';
import { UserNotificationListener } from '../user/application/notifications';
import {
@ -11,14 +8,13 @@ import {
CreateAppPayloadPB,
CreateWorkspacePayloadPB,
FolderEventCreateApp,
FolderEventCreateView,
FolderEventCreateWorkspace,
FolderEventOpenWorkspace,
FolderEventReadCurrentWorkspace,
WorkspaceIdPB,
} from '../../../services/backend/events/flowy-folder';
import { useEffect, useState } from 'react';
import * as dependency_1 from '../../../services/backend/classes/flowy-folder/app';
import * as dependency_1 from '../../../services/backend/models/flowy-folder/app';
import { UserEventGetUserSetting, UserEventSignIn } from '../../../services/backend/events/flowy-user';
const TestApiButton = () => {
const [workspaceId, setWorkspaceId] = useState('');
@ -59,14 +55,14 @@ const TestApiButton = () => {
}, [workspaceId]);
async function sendSignInEvent() {
let make_payload = () =>
const make_payload = () =>
SignInPayloadPB.fromObject({
email: nanoid(4) + '@gmail.com',
password: 'A!@123abc',
name: 'abc',
});
let listener = new UserNotificationListener({
const listener = new UserNotificationListener({
onUserSignIn: (userProfile) => {
console.log(userProfile);
},

View File

@ -1,6 +1,6 @@
import { useState } from 'react';
import { currentUserActions } from '../../../redux/current-user/slice';
import { useAppDispatch, useAppSelector } from '../../../store';
import { currentUserActions } from '../../../stores/reducers/current-user/slice';
import { useAppDispatch, useAppSelector } from '../../../stores/store';
import { useNavigate } from 'react-router-dom';
export const useConfirmAccount = () => {

View File

@ -1,6 +1,6 @@
import { useState } from 'react';
import { currentUserActions } from '../../../redux/current-user/slice';
import { useAppDispatch, useAppSelector } from '../../../store';
import { currentUserActions } from '../../../stores/reducers/current-user/slice';
import { useAppDispatch, useAppSelector } from '../../../stores/store';
import { useNavigate } from 'react-router-dom';
export const useLogin = () => {

View File

@ -1,6 +1,6 @@
import { useState } from 'react';
import { useAppDispatch, useAppSelector } from '../../../store';
import { currentUserActions } from '../../../redux/current-user/slice';
import { useAppDispatch, useAppSelector } from '../../../stores/store';
import { currentUserActions } from '../../../stores/reducers/current-user/slice';
import { useNavigate } from 'react-router-dom';
export const useSignUp = () => {

View File

@ -1,5 +1,5 @@
import { currentUserActions } from '../../redux/current-user/slice';
import { useAppDispatch, useAppSelector } from '../../store';
import { currentUserActions } from '../../stores/reducers/current-user/slice';
import { useAppDispatch, useAppSelector } from '../../stores/store';
export const useAuth = () => {
const dispatch = useAppDispatch();

View File

@ -1,4 +1,4 @@
import { useAppSelector } from '../../../store';
import { useAppSelector } from '../../../stores/store';
export const useGridTableCount = () => {
const { grid } = useAppSelector((state) => state);

View File

@ -1,7 +1,7 @@
import { nanoid } from 'nanoid';
import { FieldType } from '../../../../services/backend/classes/flowy-database/field_entities';
import { gridActions } from '../../../redux/grid/slice';
import { useAppDispatch, useAppSelector } from '../../../store';
import { FieldType } from '../../../../services/backend/models/flowy-database/field_entities';
import { gridActions } from '../../../stores/reducers/grid/slice';
import { useAppDispatch, useAppSelector } from '../../../stores/store';
export const useGridTableHeaderHooks = function () {
const dispatch = useAppDispatch();

View File

@ -7,7 +7,7 @@ import { SingleSelectTypeSvg } from '../../_shared/svg/SingleSelectTypeSvg';
import { MultiSelectTypeSvg } from '../../_shared/svg/MultiSelectTypeSvg';
import { ChecklistTypeSvg } from '../../_shared/svg/ChecklistTypeSvg';
import { UrlTypeSvg } from '../../_shared/svg/UrlTypeSvg';
import { FieldType } from '../../../../services/backend/classes/flowy-database/field_entities';
import { FieldType } from '../../../../services/backend/models/flowy-database/field_entities';
export const GridTableHeader = () => {
const { fields, onAddField } = useGridTableHeaderHooks();

View File

@ -1,5 +1,5 @@
import { gridActions } from '../../../redux/grid/slice';
import { useAppDispatch } from '../../../store';
import { gridActions } from '../../../stores/reducers/grid/slice';
import { useAppDispatch } from '../../../stores/store';
export const useGridAddRow = () => {
const dispatch = useAppDispatch();

View File

@ -1,6 +1,6 @@
import { useState } from 'react';
import { gridActions } from '../../../redux/grid/slice';
import { useAppDispatch, useAppSelector } from '../../../store';
import { gridActions } from '../../../stores/reducers/grid/slice';
import { useAppDispatch, useAppSelector } from '../../../stores/store';
export const useGridTableItemHooks = (
rowItem: { value: string | number; fieldId: string; cellId: string },

View File

@ -1,4 +1,4 @@
import { useAppSelector } from '../../../store';
import { useAppSelector } from '../../../stores/store';
export const useGridTableRowsHooks = () => {
const grid = useAppSelector((state) => state.grid);

View File

@ -1,7 +1,7 @@
import { useState } from 'react';
import { gridActions } from '../../../redux/grid/slice';
import { gridActions } from '../../../stores/reducers/grid/slice';
import { useAppDispatch, useAppSelector } from '../../../store';
import { useAppDispatch, useAppSelector } from '../../../stores/store';
export const useGridTitleHooks = function () {
const dispatch = useAppDispatch();

View File

@ -1,8 +1,8 @@
import { foldersActions, IFolder } from '../../../redux/folders/slice';
import { foldersActions, IFolder } from '../../../stores/reducers/folders/slice';
import { useState } from 'react';
import { useAppDispatch } from '../../../store';
import { useAppDispatch } from '../../../stores/store';
import { nanoid } from 'nanoid';
import { pagesActions } from '../../../redux/pages/slice';
import { pagesActions } from '../../../stores/reducers/pages/slice';
export const useFolderEvents = (folder: IFolder) => {
const appDispatch = useAppDispatch();

View File

@ -2,9 +2,9 @@ import { Details2Svg } from '../../_shared/svg/Details2Svg';
import AddSvg from '../../_shared/svg/AddSvg';
import { NavItemOptionsPopup } from './NavItemOptionsPopup';
import { NewPagePopup } from './NewPagePopup';
import { IFolder } from '../../../redux/folders/slice';
import { IFolder } from '../../../stores/reducers/folders/slice';
import { useFolderEvents } from './FolderItem.hooks';
import { IPage } from '../../../redux/pages/slice';
import { IPage } from '../../../stores/reducers/pages/slice';
import { PageItem } from './PageItem';
import { Button } from '../../_shared/Button';
import { RenamePopup } from './RenamePopup';

View File

@ -1,4 +1,4 @@
import { useAppSelector } from '../../../store';
import { useAppSelector } from '../../../stores/store';
import { useNavigate } from 'react-router-dom';
export const useNavigationPanelHooks = function () {

View File

@ -1,7 +1,7 @@
import { useResizer } from '../../_shared/useResizer';
import { useAppDispatch, useAppSelector } from '../../../store';
import { useAppDispatch, useAppSelector } from '../../../stores/store';
import { useEffect } from 'react';
import { navigationWidthActions } from '../../../redux/navigation-width/slice';
import { navigationWidthActions } from '../../../stores/reducers/navigation-width/slice';
export const NavigationResizer = () => {
const width = useAppSelector((state) => state.navigationWidth);

View File

@ -1,5 +1,5 @@
import { useAppDispatch } from '../../../store';
import { foldersActions } from '../../../redux/folders/slice';
import { useAppDispatch } from '../../../stores/store';
import { foldersActions } from '../../../stores/reducers/folders/slice';
import { nanoid } from 'nanoid';
export const useNewFolder = () => {

View File

@ -1,5 +1,5 @@
import { IPage, pagesActions } from '../../../redux/pages/slice';
import { useAppDispatch } from '../../../store';
import { IPage, pagesActions } from '../../../stores/reducers/pages/slice';
import { useAppDispatch } from '../../../stores/store';
import { useState } from 'react';
import { nanoid } from 'nanoid';

View File

@ -3,7 +3,7 @@ import { BoardSvg } from '../../_shared/svg/BoardSvg';
import { GridSvg } from '../../_shared/svg/GridSvg';
import { Details2Svg } from '../../_shared/svg/Details2Svg';
import { NavItemOptionsPopup } from './NavItemOptionsPopup';
import { IPage } from '../../../redux/pages/slice';
import { IPage } from '../../../stores/reducers/pages/slice';
import { Button } from '../../_shared/Button';
import { usePageEvents } from './PageItem.hooks';
import { RenamePopup } from './RenamePopup';

View File

@ -1,4 +1,4 @@
import { useAppSelector } from '../../store';
import { useAppSelector } from '../../stores/store';
export const Workspace = () => {
const currentUser = useAppSelector((state) => state.currentUser);

View File

@ -8,7 +8,7 @@ export class UserNotificationParser extends NotificationParser<UserNotification>
super(
params.callback,
(ty) => {
let notification = UserNotification[ty];
const notification = UserNotification[ty];
if (isUserNotification(notification)) {
return UserNotification[notification];
} else {

View File

@ -1,4 +1,4 @@
import { FlowyError, UserNotification, UserProfilePB } from '../../../../../services/backend';
import { UserNotification, UserProfilePB } from '../../../../../services/backend';
import { AFNotificationListener, OnNotificationError } from '../../../../../services/backend/notifications';
import { UserNotificationParser } from './parser';
@ -15,7 +15,7 @@ export class UserNotificationListener extends AFNotificationListener<UserNotific
onProfileUpdate?: OnUserProfileUpdate;
onError?: OnNotificationError;
}) {
let parser = new UserNotificationParser({
const parser = new UserNotificationParser({
callback: (notification, payload) => {
switch (notification) {
case UserNotification.DidUpdateUserProfile:

View File

@ -1 +0,0 @@
export {}

View File

@ -1 +0,0 @@
export {}

View File

@ -1,5 +1,5 @@
import { FolderNotification } from '../../../../services/backend';
import { NotificationParser, OnNotificationError } from '../../../../services/backend/notifications/parser';
import { FolderNotification } from '../../../../../services/backend';
import { NotificationParser, OnNotificationError } from '../../../../../services/backend/notifications';
declare type FolderNotificationCallback = (ty: FolderNotification, payload: Uint8Array) => void;
@ -8,7 +8,7 @@ export class FolderNotificationParser extends NotificationParser<FolderNotificat
super(
params.callback,
(ty) => {
let notification = FolderNotification[ty];
const notification = FolderNotification[ty];
if (isFolderNotification(notification)) {
return FolderNotification[notification];
} else {

View File

@ -1,14 +1,14 @@
import { DatabaseNotification } from "../../../../../services/backend";
import { NotificationParser, OnNotificationError } from "../../../../../services/backend/notifications/parser";
import { DatabaseNotification } from '../../../../../services/backend';
import { NotificationParser, OnNotificationError } from '../../../../../services/backend/notifications';
declare type DatabaseNotificationCallback = (ty: DatabaseNotification, payload: Uint8Array) => void;
export class DatabaseNotificationParser extends NotificationParser<DatabaseNotification> {
constructor(params: { id?: String; callback: DatabaseNotificationCallback; onError?: OnNotificationError }) {
constructor(params: { id?: string; callback: DatabaseNotificationCallback; onError?: OnNotificationError }) {
super(
params.callback,
(ty) => {
let notification = DatabaseNotification[ty];
const notification = DatabaseNotification[ty];
if (isDatabaseNotification(notification)) {
return DatabaseNotification[notification];
} else {

View File

@ -1,6 +1,6 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { nanoid } from 'nanoid';
import { FieldType } from '../../../services/backend/classes/flowy-database/field_entities';
import { FieldType } from '../../../../services/backend/models/flowy-database/field_entities';
const initialState = {
title: 'My plans on the week',

View File

@ -7,11 +7,11 @@ import {
ListenerEffectAPI,
addListener,
} from '@reduxjs/toolkit';
import { foldersSlice } from './redux/folders/slice';
import { pagesSlice } from './redux/pages/slice';
import { navigationWidthSlice } from './redux/navigation-width/slice';
import { currentUserSlice } from './redux/current-user/slice';
import { gridSlice } from './redux/grid/slice';
import { foldersSlice } from './reducers/folders/slice';
import { pagesSlice } from './reducers/pages/slice';
import { navigationWidthSlice } from './reducers/navigation-width/slice';
import { currentUserSlice } from './reducers/current-user/slice';
import { gridSlice } from './reducers/grid/slice';
const listenerMiddlewareInstance = createListenerMiddleware({
onError: () => console.error,

View File

@ -1,6 +1,6 @@
export * from "./classes/flowy-user";
export * from "./classes/flowy-document";
export * from "./classes/flowy-database";
export * from "./classes/flowy-folder";
export * from "./classes/flowy-net";
export * from "./classes/flowy-error";
export * from "./models/flowy-user";
export * from "./models/flowy-document";
export * from "./models/flowy-database";
export * from "./models/flowy-folder";
export * from "./models/flowy-net";
export * from "./models/flowy-error";

View File

@ -1,6 +1,6 @@
import { listen, UnlistenFn } from "@tauri-apps/api/event";
import { FlowyError } from "../classes/flowy-error";
import { SubscribeObject } from "../classes/flowy-notification";
import { FlowyError } from "../models/flowy-error";
import { SubscribeObject } from "../models/flowy-notification";
import { NotificationParser } from "./parser";
declare type OnError = (error: FlowyError) => void;

View File

@ -1,6 +1,6 @@
import { Ok, Err, Result } from "ts-results/result";
import { FlowyError } from "../classes/flowy-error";
import { SubscribeObject } from "../classes/flowy-notification";
import { FlowyError } from "../models/flowy-error";
import { SubscribeObject } from "../models/flowy-notification";
export declare type OnNotificationPayload<T> = (ty: T, payload: Uint8Array) => void;
export declare type OnNotificationError = (error: FlowyError) => void;

View File

@ -119,7 +119,7 @@ fn generate_ts_protobuf_files(
let mut output = PathBuf::new();
output.push(root);
output.push(tauri_backend_service_path);
output.push("classes");
output.push("models");
output.push(name);
if !output.as_path().exists() {

View File

@ -81,7 +81,7 @@ pub fn gen(crate_name: &str) {
Ok(ref mut file) => {
let mut export = String::new();
export.push_str("// Auto-generated, do not edit \n");
export.push_str(&format!("export * from '../../classes/{}';\n", crate_name));
export.push_str(&format!("export * from '../../models/{}';\n", crate_name));
export.push_str(&format!("export * from './{}';\n", event_file));
file.write_all(export.as_bytes()).unwrap();
File::flush(file).unwrap();

View File

@ -27,7 +27,7 @@ run_task = { name = [
[tasks.rm_tauri_generated_protobuf_files]
private = true
script = ["""
protobuf_file_paths = glob_array ${TAURI_BACKEND_SERVICE_PATH}/classes
protobuf_file_paths = glob_array ${TAURI_BACKEND_SERVICE_PATH}/models
if not array_is_empty ${protobuf_file_paths}
echo Remove generated protobuf files:
for path in ${protobuf_file_paths}