Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: List application api by label #727

Merged
merged 6 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions e2e-test/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
)

var appName = "app-e2e"
var appName2 = "app-e2e-2"
var appProject = "test-app-project"

func prepareEnv(envName string) {
Expand Down Expand Up @@ -67,6 +68,29 @@ var _ = Describe("Test application rest api", func() {
Project: appProject,
Description: "this is a test app",
Icon: "",
Labels: map[string]string{"test": "true"},
EnvBinding: []*apisv1.EnvBinding{{Name: "dev-env"}},
Component: &apisv1.CreateComponentRequest{
Name: "webservice",
ComponentType: "webservice",
Properties: "{\"image\":\"nginx\"}",
},
}
res := post("/applications", req)
var appBase apisv1.ApplicationBase
Expect(decodeResponseBody(res, &appBase)).Should(Succeed())
Expect(cmp.Diff(appBase.Name, req.Name)).Should(BeEmpty())
Expect(cmp.Diff(appBase.Description, req.Description)).Should(BeEmpty())
Expect(cmp.Diff(appBase.Labels["test"], req.Labels["test"])).Should(BeEmpty())
})

It("Test create second app", func() {
defer GinkgoRecover()
var req = apisv1.CreateApplicationRequest{
Name: appName2,
Project: appProject,
Description: "this is another test app",
Icon: "",
Labels: map[string]string{"test": "true", "labelselector": "true"},
EnvBinding: []*apisv1.EnvBinding{{Name: "dev-env"}},
Component: &apisv1.CreateComponentRequest{
Expand Down
1 change: 1 addition & 0 deletions packages/velaux-ui/src/interface/application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@ export interface ApplicationQuery {
project?: string;
env?: string;
targetName?: string;
labels?: string;
}

export interface ComponentDefinitionsBase {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class SelectSearch extends React.Component<Props, State> {
const { Row, Col } = Grid;
const { Option } = Select;
const { registries } = this.props;
const queryPlaceholder = i18n.t('Search by name and description etc').toString();
const queryPlaceholder = i18n.t('Search by Name and Description etc').toString();
const { registryValue, inputValue } = this.state;

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,9 @@ class SelectSearch extends React.Component<Props, State> {
const { projectValue, inputValue, envValue } = this.state;

const projectPlaceholder = i18n.t('Search by Project').toString();
const appPlaceholder = i18n.t('Search by name and description etc').toString();
const appPlaceholder = i18n.t('Search by Name and Description etc').toString();
const envPlaceholder = i18n.t('Search by Environment').toString();
const labelPlaceholder = i18n.t('Search by labels').toString();
const labelPlaceholder = i18n.t('Search by Label Selector').toString();
const projectSource = projects?.map((item) => {
return {
label: item.alias || item.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class InputSearch extends React.Component<Props, State> {
<Col span="24">
<Input
innerAfter={<AiOutlineSearch onClick={this.handleClickSearch} style={{ margin: 4 }} />}
placeholder={i18n.t('Search by name and description etc').toString()}
placeholder={i18n.t('Search by Name and Description etc').toString()}
onChange={this.handleChangName}
onPressEnter={this.handleClickSearch}
value={inputValue}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class SelectSearch extends React.Component<Props, State> {
const { projectValue, inputValue } = this.state;

const projectPlaceholder = i18n.t('Search by Project').toString();
const appPlaceholder = i18n.t('Search by name and description etc').toString();
const appPlaceholder = i18n.t('Search by Name and Description etc').toString();
const projectSource = projects?.map((item) => {
return {
label: item.alias || item.name,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ type Props = {
envs?: Env[];
listApplication: (params: any) => void;
onAddApplication: () => void;
setLabelValue: (labels: string[]) => void;
appLabels?: string[];
labelValue?: string[];
projectName?: string;
showMode: ShowMode;
setMode: (mode: ShowMode) => void;
Expand All @@ -26,6 +29,7 @@ type State = {
targetValue: string;
inputValue: string;
envValue: string;
labelValue: string[];
};

class SelectSearch extends React.Component<Props, State> {
Expand All @@ -35,6 +39,7 @@ class SelectSearch extends React.Component<Props, State> {
targetValue: '',
envValue: '',
inputValue: '',
labelValue: [],
};
this.onChangeTarget = this.onChangeTarget.bind(this);
this.handleChangName = this.handleChangName.bind(this);
Expand Down Expand Up @@ -68,6 +73,18 @@ class SelectSearch extends React.Component<Props, State> {
);
};

handleChangeLabel(value: string[]) {
const { setLabelValue } = this.props;
let label = value? value:[]
setLabelValue(label)
this.setState({
labelValue: label,
},
() => {
this.getApplications();
});
};

handleClickSearch = () => {
this.getApplications();
};
Expand All @@ -92,7 +109,7 @@ class SelectSearch extends React.Component<Props, State> {
};

render() {
const { targetList, envs, projectName, showMode } = this.props;
const { targetList, envs, projectName, showMode, labelValue, appLabels } = this.props;
const { targetValue, inputValue, envValue } = this.state;
const targetSource = targetList?.map((item) => {
return {
Expand All @@ -107,12 +124,20 @@ class SelectSearch extends React.Component<Props, State> {
value: env.name,
};
});

const labelSource = appLabels?.map((item) => {
return {
label: item,
value: item,
};
});

return (
<Fragment>
<Row className="project-select-wrapper border-radius-8 margin-top-20">
<Col span="20">
<Row wrap={true}>
basuotian marked this conversation as resolved.
Show resolved Hide resolved
<Col xl={6} m={8} s={12} xxs={24} style={{ padding: '0 8px' }}>
<Col xl={6} m={4} s={6} xxs={24} style={{ padding: '0 8px' }}>
<Select
locale={locale().Select}
mode="single"
Expand All @@ -125,7 +150,7 @@ class SelectSearch extends React.Component<Props, State> {
value={envValue}
/>
</Col>
<Col xl={6} m={8} s={12} xxs={24} style={{ padding: '0 8px' }}>
<Col xl={6} m={4} s={6} xxs={24} style={{ padding: '0 8px' }}>
<Select
locale={locale().Select}
mode="single"
Expand All @@ -138,12 +163,25 @@ class SelectSearch extends React.Component<Props, State> {
value={targetValue}
/>
</Col>
<Col xl={6} m={8} s={12} xxs={24} style={{ padding: '0 8px' }}>
<Select
hasClear
size="large"
placeholder={i18n.t('Search by Label Selector').toString()}
onChange={this.handleChangeLabel}
Fixed Show fixed Hide fixed
showSearch
mode="multiple"
value={labelValue}
className="item"
dataSource={labelSource}
/>
</Col>
<Col xl={6} m={8} s={12} xxs={24} style={{ padding: '0 8px' }}>
<Input
innerAfter={<Icon type="search" size="xs" onClick={this.handleClickSearch} style={{ margin: 4 }} />}
hasClear
size="large"
placeholder={i18n.t('Search by name and description etc')}
placeholder={i18n.t('Search by Name and Description etc')}
onChange={this.handleChangName}
onPressEnter={this.handleClickSearch}
value={inputValue}
Expand Down
44 changes: 43 additions & 1 deletion packages/velaux-ui/src/pages/ProjectApplications/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ type State = {
componentDefinitions: [];
isEditApplication: boolean;
isAddApplication: boolean;
labelValue: string[];
showMode: ShowMode;
};

Expand All @@ -62,6 +63,7 @@ class ProjectApplications extends Component<Props, State> {
},
envs: [],
componentDefinitions: [],
labelValue: [],
isEditApplication: false,
isAddApplication: false,
showMode: mode,
Expand All @@ -77,11 +79,12 @@ class ProjectApplications extends Component<Props, State> {

listApplication = async (queryData?: ApplicationQuery) => {
const { params = { projectName: '' } } = this.props.match;
const { query = '', env = '', targetName = '' } = queryData || {};
const { query = '', env = '', targetName = '', labels = '', } = queryData || {};
const queryParams: ApplicationQuery = {
query,
env,
targetName,
labels,
project: params.projectName,
};
this.setState({ isLoading: true });
Expand Down Expand Up @@ -125,6 +128,12 @@ class ProjectApplications extends Component<Props, State> {
});
};

setLabelValue = async (labels: string[]) => {
this.setState({
labelValue: labels,
});
};

editApplicationPlan = (editApplicationItem: ApplicationBase) => {
this.setState({
editApplicationItem,
Expand Down Expand Up @@ -155,6 +164,26 @@ class ProjectApplications extends Component<Props, State> {
this.listApplication();
};

clickLabelFilter = (label: string) => {
let { labelValue } = this.state;
let existIndex = -1;
labelValue.map((key, index) => {
if (key == label) {
existIndex = index
return
}
});
if (existIndex == -1) {
labelValue.push(label)
} else {
labelValue = labelValue.splice(existIndex, existIndex);
}
this.setState({
labelValue
});
this.listApplication({labels: labelValue.join(",")});
};

render() {
const { dispatch, userInfo } = this.props;
const {
Expand All @@ -166,16 +195,28 @@ class ProjectApplications extends Component<Props, State> {
targets,
envs,
componentDefinitions,
labelValue,
} = this.state;
const { params = { projectName: '' } } = this.props.match;
const { projectName } = params;
let appLabels: string[] = []
applicationList.map((app) => {
app.labels && Object.keys(app.labels).map((key: string) => {
if (key.indexOf("ux.oam.dev") < 0 && key.indexOf("app.oam.dev")) {
if (app.labels) { appLabels.push(key+"="+app.labels[key]) }
}
})
})

return (
<Fragment>
<div className="full-container">
<SelectSearch
targetList={targets}
envs={envs}
appLabels={appLabels}
setLabelValue={this.setLabelValue}
labelValue={labelValue}
projectName={projectName}
listApplication={(queryData: ApplicationQuery) => {
this.listApplication(queryData);
Expand All @@ -199,6 +240,7 @@ class ProjectApplications extends Component<Props, State> {
this.editApplicationPlan(editItem);
}}
showMode={this.state.showMode}
clickLabelFilter={this.clickLabelFilter}
deleteAppPlan={this.onDeleteApplicationItem}
setVisible={(visible) => {
this.setState({ isAddApplication: visible });
Expand Down
11 changes: 11 additions & 0 deletions pkg/server/domain/service/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,17 @@ func listApp(ctx context.Context, ds datastore.DataStore, listOptions apisv1.Lis
continue
}
}
if len(listOptions.Labels) > 0 {
matchLabels := false
for k, v := range listOptions.Labels {
if appModel.Labels != nil && appModel.Labels[k] == v {
matchLabels = true
}
}
if !matchLabels {
continue
}
}
list = append(list, appModel)
}
return list, nil
Expand Down