mirror of https://github.com/openspug/spug
A app list supports sorting
parent
573d6db725
commit
f0f55395b6
|
@ -14,6 +14,7 @@ class App(models.Model, ModelMixin):
|
||||||
desc = models.CharField(max_length=255, null=True)
|
desc = models.CharField(max_length=255, null=True)
|
||||||
rel_apps = models.TextField(null=True)
|
rel_apps = models.TextField(null=True)
|
||||||
rel_services = models.TextField(null=True)
|
rel_services = models.TextField(null=True)
|
||||||
|
sort_id = models.IntegerField(default=0, db_index=True)
|
||||||
created_at = models.CharField(max_length=20, default=human_datetime)
|
created_at = models.CharField(max_length=20, default=human_datetime)
|
||||||
created_by = models.ForeignKey(User, on_delete=models.PROTECT)
|
created_by = models.ForeignKey(User, on_delete=models.PROTECT)
|
||||||
|
|
||||||
|
@ -28,7 +29,7 @@ class App(models.Model, ModelMixin):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
db_table = 'apps'
|
db_table = 'apps'
|
||||||
ordering = ('-id',)
|
ordering = ('-sort_id',)
|
||||||
|
|
||||||
|
|
||||||
class Deploy(models.Model, ModelMixin):
|
class Deploy(models.Model, ModelMixin):
|
||||||
|
|
|
@ -12,6 +12,13 @@ import subprocess
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
# v2.3.14 临时数据初始化
|
||||||
|
ap = App.objects.first()
|
||||||
|
if ap and ap.sort_id == 0:
|
||||||
|
for ap in App.objects.all():
|
||||||
|
ap.sort_id = ap.id
|
||||||
|
ap.save()
|
||||||
|
|
||||||
|
|
||||||
class AppView(View):
|
class AppView(View):
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
@ -37,6 +44,8 @@ class AppView(View):
|
||||||
App.objects.filter(pk=form.id).update(**form)
|
App.objects.filter(pk=form.id).update(**form)
|
||||||
else:
|
else:
|
||||||
app = App.objects.create(created_by=request.user, **form)
|
app = App.objects.create(created_by=request.user, **form)
|
||||||
|
app.sort_id = app.id
|
||||||
|
app.save()
|
||||||
if request.user.role:
|
if request.user.role:
|
||||||
request.user.role.add_deploy_perm('apps', app.id)
|
request.user.role.add_deploy_perm('apps', app.id)
|
||||||
return json_response(error=error)
|
return json_response(error=error)
|
||||||
|
@ -45,14 +54,25 @@ class AppView(View):
|
||||||
form, error = JsonParser(
|
form, error = JsonParser(
|
||||||
Argument('id', type=int, help='参数错误'),
|
Argument('id', type=int, help='参数错误'),
|
||||||
Argument('rel_apps', type=list, required=False),
|
Argument('rel_apps', type=list, required=False),
|
||||||
Argument('rel_services', type=list, required=False)
|
Argument('rel_services', type=list, required=False),
|
||||||
|
Argument('sort', filter=lambda x: x in ('up', 'down'), required=False)
|
||||||
).parse(request.body)
|
).parse(request.body)
|
||||||
if error is None:
|
if error is None:
|
||||||
app = App.objects.filter(pk=form.id).first()
|
app = App.objects.filter(pk=form.id).first()
|
||||||
if not app:
|
if not app:
|
||||||
return json_response(error='未找到指定应用')
|
return json_response(error='未找到指定应用')
|
||||||
app.rel_apps = json.dumps(form.rel_apps)
|
if form.rel_apps is not None:
|
||||||
app.rel_services = json.dumps(form.rel_services)
|
app.rel_apps = json.dumps(form.rel_apps)
|
||||||
|
if form.rel_services is not None:
|
||||||
|
app.rel_services = json.dumps(form.rel_services)
|
||||||
|
if form.sort:
|
||||||
|
if form.sort == 'up':
|
||||||
|
tmp = App.objects.filter(sort_id__gt=app.sort_id).last()
|
||||||
|
else:
|
||||||
|
tmp = App.objects.filter(sort_id__lt=app.sort_id).first()
|
||||||
|
if tmp:
|
||||||
|
tmp.sort_id, app.sort_id = app.sort_id, tmp.sort_id
|
||||||
|
tmp.save()
|
||||||
app.save()
|
app.save()
|
||||||
return json_response(error=error)
|
return json_response(error=error)
|
||||||
|
|
||||||
|
@ -78,7 +98,7 @@ class DeployView(View):
|
||||||
perms = request.user.deploy_perms
|
perms = request.user.deploy_perms
|
||||||
form.app_id__in = perms['apps']
|
form.app_id__in = perms['apps']
|
||||||
form.env_id__in = perms['envs']
|
form.env_id__in = perms['envs']
|
||||||
deploys = Deploy.objects.filter(**form).annotate(app_name=F('app__name'))
|
deploys = Deploy.objects.filter(**form).annotate(app_name=F('app__name')).order_by('-app__sort_id')
|
||||||
return json_response(deploys)
|
return json_response(deploys)
|
||||||
|
|
||||||
def post(self, request):
|
def post(self, request):
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { toJS } from 'mobx';
|
import { toJS } from 'mobx';
|
||||||
import { observer } from 'mobx-react';
|
import { observer } from 'mobx-react';
|
||||||
import { Table, Modal, Tag, Icon, message } from 'antd';
|
import { Table, Modal, Tag, Icon, Divider, message } from 'antd';
|
||||||
import { http, hasPermission } from 'libs';
|
import { http, hasPermission } from 'libs';
|
||||||
import store from './store';
|
import store from './store';
|
||||||
import { Action } from "components";
|
import { Action } from "components";
|
||||||
|
@ -76,6 +76,13 @@ class ComTable extends React.Component {
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleSort = (e, info, sort) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
store.fetching = true;
|
||||||
|
http.patch('/api/app/', {id: info.id, sort})
|
||||||
|
.then(store.fetchRecords, () => store.fetching = false)
|
||||||
|
};
|
||||||
|
|
||||||
expandedRowRender = (record) => {
|
expandedRowRender = (record) => {
|
||||||
if (record['deploys'] === undefined) {
|
if (record['deploys'] === undefined) {
|
||||||
store.loadDeploys(record.id)
|
store.loadDeploys(record.id)
|
||||||
|
@ -131,7 +138,15 @@ class ComTable extends React.Component {
|
||||||
showTotal: total => `共 ${total} 条`,
|
showTotal: total => `共 ${total} 条`,
|
||||||
pageSizeOptions: ['10', '20', '50', '100']
|
pageSizeOptions: ['10', '20', '50', '100']
|
||||||
}}>
|
}}>
|
||||||
<Table.Column width={80} title="序号" key="series" render={(_, __, index) => index + 1}/>
|
<Table.Column width={80} title="排序" key="series" render={(info) => (
|
||||||
|
<div>
|
||||||
|
<Icon onClick={e => this.handleSort(e, info, 'up')} type="up-square"
|
||||||
|
style={{cursor: 'pointer', color: '#1890ff'}}/>
|
||||||
|
<Divider type="vertical"/>
|
||||||
|
<Icon onClick={e => this.handleSort(e, info, 'down')} type="down-square"
|
||||||
|
style={{cursor: 'pointer', color: '#1890ff'}}/>
|
||||||
|
</div>
|
||||||
|
)}/>
|
||||||
<Table.Column title="应用名称" dataIndex="name"/>
|
<Table.Column title="应用名称" dataIndex="name"/>
|
||||||
<Table.Column title="标识符" dataIndex="key"/>
|
<Table.Column title="标识符" dataIndex="key"/>
|
||||||
<Table.Column ellipsis title="描述信息" dataIndex="desc"/>
|
<Table.Column ellipsis title="描述信息" dataIndex="desc"/>
|
||||||
|
|
Loading…
Reference in New Issue