Compare commits

..

1 Commits

Author SHA1 Message Date
xue jiahao
e362c80e98 show domain page for all user
1. show ドメイン管理
2. hide ドメイン適用
3. force redirect to domain page if user no domain exist
2024-11-06 21:56:14 +08:00
11 changed files with 48 additions and 159 deletions

4
.gitignore vendored
View File

@@ -1,7 +1,3 @@
.vscode
.mypy_cache
docker-stack.yml
backend/pyvenv.cfg
backend/Include/
backend/Scripts/

View File

@@ -9,35 +9,6 @@ from app.core.apiexception import APIException
platform_router = r = APIRouter()
@r.get(
"/apps",
response_model=List[AppList],
response_model_exclude_none=True,
)
async def apps_list(
request: Request,
db=Depends(get_db),
):
try:
app = get_apps(db)
return app
except Exception as e:
raise APIException('platform:apps',request.url._url,f"Error occurred while get apps:",e)
@r.post("/apps", response_model=AppList, response_model_exclude_none=True)
async def apps_update(
request: Request,
app: AppVersion,
user=Depends(get_current_user),
db=Depends(get_db),
):
try:
return update_appversion(db, app,user.id)
except Exception as e:
raise APIException('platform:apps',request.url._url,f"Error occurred while get create app :",e)
@r.get(
"/appsettings/{id}",
response_model=App,

View File

@@ -5,7 +5,7 @@ import base64
PROJECT_NAME = "KintoneAppBuilder"
#SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@kintonetooldb.postgres.database.azure.com/dev"
SQLALCHEMY_DATABASE_URI = f"postgresql+psycopg2://kabAdmin:P%40ssw0rd!@kintonetooldb.postgres.database.azure.com/postgres"
SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@kintonetooldb.postgres.database.azure.com/postgres"
#SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@kintonetooldb.postgres.database.azure.com/test"
#SQLALCHEMY_DATABASE_URI = "postgres://kabAdmin:P@ssw0rd!@ktune-prod-db.postgres.database.azure.com/postgres"
API_V1_STR = "/k/v1"

View File

@@ -69,29 +69,6 @@ def edit_user(
db.refresh(db_user)
return db_user
def get_apps(
db: Session
) -> t.List[schemas.AppList]:
return db.query(models.App).all()
def update_appversion(db: Session, appedit: schemas.AppVersion,userid:int):
app = db.query(models.App).filter(and_(models.App.domainurl == appedit.domainurl,models.App.appid == appedit.appid)).first()
if app:
app.version = app.version + 1
db_app = app
else:
db_app = models.App(
domainurl = appedit.domainurl,
appid=appedit.appid,
appname=appedit.appname,
version = 1,
updateuser= userid
)
db.add(db_app)
db.commit()
db.refresh(db_app)
return db_app
def get_appsetting(db: Session, id: int):
app = db.query(models.AppSetting).get(id)

View File

@@ -1,6 +1,5 @@
from sqlalchemy import Boolean, Column, Integer, String, DateTime,ForeignKey
from sqlalchemy.ext.declarative import as_declarative
from sqlalchemy.orm import relationship
from datetime import datetime
from app.core.security import chacha20Decrypt
@@ -21,16 +20,6 @@ class User(Base):
is_active = Column(Boolean, default=True)
is_superuser = Column(Boolean, default=False)
class App(Base):
__tablename__ = "app"
domainurl = Column(String(200), nullable=False)
appname = Column(String(200), nullable=False)
appid = Column(String(100), index=True, nullable=False)
version = Column(Integer)
updateuser = Column(Integer,ForeignKey("user.id"))
user = relationship('User')
class AppSetting(Base):
__tablename__ = "appsetting"

View File

@@ -28,21 +28,21 @@ class UserCreate(UserBase):
is_active:bool
is_superuser:bool
class ConfigDict:
class Config:
orm_mode = True
class UserEdit(UserBase):
password: t.Optional[str] = None
class ConfigDict:
class Config:
orm_mode = True
class User(UserBase):
id: int
class ConfigDict:
class Config:
orm_mode = True
@@ -50,17 +50,6 @@ class Token(BaseModel):
access_token: str
token_type: str
class AppList(Base):
domainurl: str
appname: str
appid:str
version:int
user:UserOut
class AppVersion(BaseModel):
domainurl: str
appname: str
appid:str
class TokenData(BaseModel):
id:int = 0
@@ -79,7 +68,7 @@ class AppBase(BaseModel):
class App(AppBase):
id: int
class ConfigDict:
class Config:
orm_mode = True
@@ -90,7 +79,7 @@ class Kintone(BaseModel):
desc: str = None
content: str = None
class ConfigDict:
class Config:
orm_mode = True
class Action(BaseModel):
@@ -103,7 +92,7 @@ class Action(BaseModel):
categoryid: int = None
nosort: int
categoryname : str =None
class ConfigDict:
class Config:
orm_mode = True
class FlowBase(BaseModel):
@@ -122,7 +111,7 @@ class Flow(Base):
name: str = None
content: str = None
class ConfigDict:
class Config:
orm_mode = True
class DomainBase(BaseModel):
@@ -144,7 +133,7 @@ class Domain(Base):
url: str
kintoneuser: str
kintonepwd: str
class ConfigDict:
class Config:
orm_mode = True
class Event(Base):
@@ -156,7 +145,7 @@ class Event(Base):
mobile: bool
eventgroup: bool
class ConfigDict:
class Config:
orm_mode = True
class ErrorCreate(BaseModel):

Binary file not shown.

View File

@@ -4,6 +4,7 @@
tag="a"
:target="target?target:'_blank'"
:href="link"
:disable="disable"
v-if="!isSeparator"
>
<q-item-section
@@ -33,6 +34,7 @@ export interface EssentialLinkProps {
icon?: string;
isSeparator?: boolean;
target?:string;
disable?:boolean;
}
withDefaults(defineProps<EssentialLinkProps>(), {
caption: '',

View File

@@ -22,6 +22,8 @@
<div v-if="isAdmin()">
<EssentialLink v-for="link in adminLinks" :key="link.title" v-bind="link" />
</div>
<EssentialLink v-for="link in domainLinks" :key="link.title" v-bind="link" />
</q-list>
</q-drawer>
@@ -32,7 +34,7 @@
</template>
<script setup lang="ts">
import { onMounted } from 'vue';
import { onMounted, computed } from 'vue';
import EssentialLink, { EssentialLinkProps } from 'components/EssentialLink.vue';
import DomainSelector from 'components/DomainSelector.vue';
import { useAuthStore } from 'stores/useAuthStore';
@@ -45,14 +47,16 @@ const essentialLinks: EssentialLinkProps[] = [
caption: '設計書から導入する',
icon: 'home',
link: '/',
target: '_self'
target: '_self',
disable: !authStore.hasDomain,
},
{
title: 'フローエディター',
caption: 'イベントを設定する',
icon: 'account_tree',
link: '/#/FlowChart',
target: '_self'
target: '_self',
disable: !authStore.hasDomain,
},
// {
// title: '条件エディター',
@@ -83,58 +87,23 @@ const essentialLinks: EssentialLinkProps[] = [
// link:'https://cybozu.dev/ja/kintone/docs/',
// icon:'help_outline'
// },
];
const domainLinks: EssentialLinkProps[] = [
{
title: 'ドメイン管理',
caption: 'kintoneのドメイン設定',
icon: 'domain',
link: '/#/domain',
target: '_self'
},
// {
// title:'',
// isSeparator:true
// title: 'ドメイン適用',
// caption: 'ユーザー使用可能なドメインの設定',
// icon: 'assignment_ind',
// link: '/#/userDomain',
// target: '_self'
// },
// {
// title: 'Docs',
// caption: 'quasar.dev',
// icon: 'school',
// link: 'https://quasar.dev'
// },
// {
// title: 'Icons',
// caption: 'Material Icons',
// icon: 'insert_emoticon',
// link: 'https://fonts.google.com/icons?selected=Material+Icons:insert_emoticon:'
// },
// {
// title: 'Github',
// caption: 'github.com/quasarframework',
// icon: 'code',
// link: 'https://github.com/quasarframework'
// },
// {
// title: 'Discord Chat Channel',
// caption: 'chat.quasar.dev',
// icon: 'chat',
// link: 'https://chat.quasar.dev'
// },
// {
// title: 'Forum',
// caption: 'forum.quasar.dev',
// icon: 'record_voice_over',
// link: 'https://forum.quasar.dev'
// },
// {
// title: 'Twitter',
// caption: '@quasarframework',
// icon: 'rss_feed',
// link: 'https://twitter.quasar.dev'
// },
// {
// title: 'Facebook',
// caption: '@QuasarFramework',
// icon: 'public',
// link: 'https://facebook.quasar.dev'
// },
// {
// title: 'Quasar Awesome',
// caption: 'Community Quasar projects',
// icon: 'favorite',
// link: 'https://awesome.quasar.dev'
// }
];
const adminLinks: EssentialLinkProps[] = [
@@ -145,20 +114,6 @@ const adminLinks: EssentialLinkProps[] = [
link: '/#/user',
target: '_self'
},
{
title: 'ドメイン管理',
caption: 'kintoneのドメイン設定',
icon: 'domain',
link: '/#/domain',
target: '_self'
},
{
title: 'ドメイン適用',
caption: 'ユーザー使用可能なドメインの設定',
icon: 'assignment_ind',
link: '/#/userDomain',
target: '_self'
},
]
const version = process.env.version;

View File

@@ -47,6 +47,13 @@ export default route(function (/* { store, ssrContext } */) {
authStore.returnUrl = to.fullPath;
return '/login';
}
// redirect to domain setting page if no domain exist
const domainPages = [...publicPages, '/domain'];
if (!authStore.hasDomain && !domainPages.includes(to.path)) {
authStore.returnUrl = to.fullPath;
return '/domain';
}
});
return routerInstance;
});

View File

@@ -33,6 +33,9 @@ export const useAuthStore = defineStore('auth', {
toggleLeftDrawer(): boolean {
return this.LeftDrawer;
},
hasDomain(): boolean {
return this.currentDomain.id === null;
}
},
actions: {
toggleLeftMenu() {
@@ -60,11 +63,11 @@ export const useAuthStore = defineStore('auth', {
}
},
async getCurrentDomain(): Promise<IDomainInfo> {
const activedomain = await api.get(`api/activedomain`);
const activedomain = (await api.get(`api/activedomain`))?.data;
return {
id: activedomain.data.id,
domainName: activedomain.data.name,
kintoneUrl: activedomain.data.url,
id: activedomain?.id,
domainName: activedomain?.name,
kintoneUrl: activedomain?.url,
};
},
async getUserDomains(): Promise<IDomainInfo[]> {