Browse Source

[Improvement-14456][UI] When making the process online the system should remind user to take care of its offline timing. (#14460)

3.2.1-prepare
calvin 12 months ago committed by GitHub
parent
commit
92d2b8e33f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 18
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java
  2. 4
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java
  3. 34
      dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java
  4. 7
      dolphinscheduler-ui/src/locales/en_US/project.ts
  5. 5
      dolphinscheduler-ui/src/locales/zh_CN/project.ts
  6. 25
      dolphinscheduler-ui/src/views/projects/workflow/definition/components/table-action.tsx
  7. 21
      dolphinscheduler-ui/src/views/projects/workflow/definition/index.tsx
  8. 99
      dolphinscheduler-ui/src/views/projects/workflow/definition/timing/use-table.ts
  9. 14
      dolphinscheduler-ui/src/views/projects/workflow/definition/use-table.ts

18
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/cases/WorkflowE2ETest.java

@ -49,6 +49,8 @@ import static org.awaitility.Awaitility.await;
class WorkflowE2ETest { class WorkflowE2ETest {
private static final String project = "test-workflow-1"; private static final String project = "test-workflow-1";
private static final String workflow = "test-workflow-1";
private static final String user = "admin"; private static final String user = "admin";
private static final String password = "dolphinscheduler123"; private static final String password = "dolphinscheduler123";
@ -86,22 +88,23 @@ class WorkflowE2ETest {
.goToNav(ProjectPage.class) .goToNav(ProjectPage.class)
.goTo(project) .goTo(project)
.goToTab(WorkflowDefinitionTab.class) .goToTab(WorkflowDefinitionTab.class)
.cancelPublishAll() .delete(workflow);
.deleteAll()
;
new NavBarPage(browser) new NavBarPage(browser)
.goToNav(ProjectPage.class) .goToNav(ProjectPage.class)
.delete(project) .delete(project);
browser.navigate().refresh();
new NavBarPage(browser)
.goToNav(SecurityPage.class) .goToNav(SecurityPage.class)
.goToTab(TenantPage.class) .goToTab(TenantPage.class)
.delete(tenant) .delete(tenant);
;
} }
@Test @Test
@Order(1) @Order(1)
void testCreateWorkflow() { void testCreateWorkflow() {
final String workflow = "test-workflow-1";
WorkflowDefinitionTab workflowDefinitionPage = WorkflowDefinitionTab workflowDefinitionPage =
new ProjectPage(browser) new ProjectPage(browser)
.goTo(project) .goTo(project)
@ -163,7 +166,6 @@ class WorkflowE2ETest {
@Test @Test
@Order(30) @Order(30)
void testRunWorkflow() { void testRunWorkflow() {
final String workflow = "test-workflow-1";
final ProjectDetailPage projectPage = final ProjectDetailPage projectPage =
new ProjectPage(browser) new ProjectPage(browser)
.goToNav(ProjectPage.class) .goToNav(ProjectPage.class)

4
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/LoginPage.java

@ -58,7 +58,7 @@ public final class LoginPage extends NavBarPage {
@SneakyThrows @SneakyThrows
public NavBarPage login(String username, String password) { public NavBarPage login(String username, String password) {
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage)); new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(buttonSwitchLanguage));
buttonSwitchLanguage().click(); buttonSwitchLanguage().click();
@ -66,7 +66,7 @@ public final class LoginPage extends NavBarPage {
inputPassword().sendKeys(password); inputPassword().sendKeys(password);
buttonLogin().click(); buttonLogin().click();
new WebDriverWait(driver, 10) new WebDriverWait(driver, 20)
.until(ExpectedConditions.urlContains("/home")); .until(ExpectedConditions.urlContains("/home"));
return new NavBarPage(driver); return new NavBarPage(driver);

34
dolphinscheduler-e2e/dolphinscheduler-e2e-case/src/test/java/org/apache/dolphinscheduler/e2e/pages/project/workflow/WorkflowDefinitionTab.java

@ -19,6 +19,9 @@
*/ */
package org.apache.dolphinscheduler.e2e.pages.project.workflow; package org.apache.dolphinscheduler.e2e.pages.project.workflow;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import lombok.Getter; import lombok.Getter;
import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage; import org.apache.dolphinscheduler.e2e.pages.common.NavBarPage;
import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage; import org.apache.dolphinscheduler.e2e.pages.project.ProjectDetailPage;
@ -30,7 +33,6 @@ import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.FindBys; import org.openqa.selenium.support.FindBys;
import java.util.List; import java.util.List;
import java.util.function.Supplier;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Getter @Getter
@ -56,6 +58,12 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
}) })
private WebElement buttonConfirm; private WebElement buttonConfirm;
@FindBys({
@FindBy(className = "n-dialog__action"),
@FindBy(className = "n-button--default-type"),
})
private WebElement publishSuccessButtonCancel;
@FindBy(className = "items") @FindBy(className = "items")
private List<WebElement> workflowList; private List<WebElement> workflowList;
@ -89,6 +97,10 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
.orElseThrow(() -> new RuntimeException("Can not find publish button in workflow definition")) .orElseThrow(() -> new RuntimeException("Can not find publish button in workflow definition"))
.click(); .click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
((JavascriptExecutor) driver).executeScript("arguments[0].click();", publishSuccessButtonCancel());
return this; return this;
} }
@ -114,11 +126,31 @@ public final class WorkflowDefinitionTab extends NavBarPage implements ProjectDe
for (WebElement cancelButton : cancelButtons) { for (WebElement cancelButton : cancelButtons) {
cancelButton.click(); cancelButton.click();
((JavascriptExecutor) driver).executeScript("arguments[0].click();", buttonConfirm());
} }
return this; return this;
} }
public WorkflowDefinitionTab delete(String workflow) {
await().untilAsserted(() -> assertThat(workflowList())
.as("Workflow list should contain newly-created workflow")
.anyMatch(
it -> it.getText().contains(workflow)
));
workflowList()
.stream()
.filter(it -> it.findElement(By.className("workflow-name")).getAttribute("innerText").equals(workflow))
.flatMap(it -> it.findElements(By.className("btn-delete")).stream())
.filter(WebElement::isDisplayed)
.findFirst()
.orElseThrow(() -> new RuntimeException("Can not find delete button in workflow definition"))
.click();
return this;
}
public WorkflowDefinitionTab deleteAll() { public WorkflowDefinitionTab deleteAll() {
if (workflowList().isEmpty()) { if (workflowList().isEmpty()) {
return this; return this;

7
dolphinscheduler-ui/src/locales/en_US/project.ts

@ -75,6 +75,8 @@ export default {
modify_user: 'Modify User', modify_user: 'Modify User',
operation: 'Operation', operation: 'Operation',
edit: 'Edit', edit: 'Edit',
confirm: 'Confirm',
cancel: 'Cancel',
start: 'Start', start: 'Start',
timing: 'Timing', timing: 'Timing',
timezone: 'Timezone', timezone: 'Timezone',
@ -226,7 +228,10 @@ export default {
workflow_relation_no_data_result_desc: workflow_relation_no_data_result_desc:
'There is not any workflows. Please create a workflow, and then visit this page again.', 'There is not any workflows. Please create a workflow, and then visit this page again.',
ready_to_block: 'Ready to block', ready_to_block: 'Ready to block',
block: 'Block' block: 'Block',
want_to_set_timing: 'Would you like to set the workflow timing?',
confirm_to_online: 'Confirm to make the workflow online?',
confirm_to_offline: 'Confirm to make the workflow offline?',
}, },
task: { task: {
on_line: 'Online', on_line: 'Online',

5
dolphinscheduler-ui/src/locales/zh_CN/project.ts

@ -226,7 +226,10 @@ export default {
workflow_relation_no_data_result_desc: workflow_relation_no_data_result_desc:
'目前没有任何工作流,请先创建工作流,再访问该页面', '目前没有任何工作流,请先创建工作流,再访问该页面',
ready_to_block: '准备锁定', ready_to_block: '准备锁定',
block: '锁定' block: '锁定',
want_to_set_timing: '现在想去配置该工作流定时?',
confirm_to_online: '是否确定上线该工作流?',
confirm_to_offline: '是否确定下线该工作流?',
}, },
task: { task: {
on_line: '线上', on_line: '线上',

25
dolphinscheduler-ui/src/views/projects/workflow/definition/components/table-action.tsx

@ -189,16 +189,25 @@ export default defineComponent({
type={releaseState === 'ONLINE' ? 'warning' : 'error'} type={releaseState === 'ONLINE' ? 'warning' : 'error'}
tag='div' tag='div'
circle circle
onClick={this.handleReleaseWorkflow}
class='btn-publish' class='btn-publish'
> >
<NIcon> <NPopconfirm onPositiveClick={this.handleReleaseWorkflow}>
{releaseState === 'ONLINE' ? ( {{
<DownloadOutlined /> default: () =>
) : ( releaseState === 'ONLINE'
<UploadOutlined /> ? t('project.workflow.confirm_to_offline')
)} : t('project.workflow.confirm_to_online'),
</NIcon> trigger: () => (
<NIcon>
{releaseState === 'ONLINE' ? (
<DownloadOutlined />
) : (
<UploadOutlined />
)}
</NIcon>
)
}}
</NPopconfirm>
</NButton> </NButton>
) )
}} }}

21
dolphinscheduler-ui/src/views/projects/workflow/definition/index.tsx

@ -23,7 +23,8 @@ import {
NPagination, NPagination,
NSpace, NSpace,
NTooltip, NTooltip,
NPopconfirm NPopconfirm,
NModal
} from 'naive-ui' } from 'naive-ui'
import { import {
defineComponent, defineComponent,
@ -59,7 +60,8 @@ export default defineComponent({
getTableData, getTableData,
batchDeleteWorkflow, batchDeleteWorkflow,
batchExportWorkflow, batchExportWorkflow,
batchCopyWorkflow batchCopyWorkflow,
gotoTimingManage
} = useTable() } = useTable()
const requestData = () => { const requestData = () => {
@ -79,6 +81,10 @@ export default defineComponent({
requestData() requestData()
} }
const confirmToSetWorkflowTiming = () => {
gotoTimingManage(variables.row)
}
const handleSearch = () => { const handleSearch = () => {
variables.page = 1 variables.page = 1
requestData() requestData()
@ -136,6 +142,7 @@ export default defineComponent({
batchExportWorkflow, batchExportWorkflow,
batchCopyWorkflow, batchCopyWorkflow,
handleCopyUpdateList, handleCopyUpdateList,
confirmToSetWorkflowTiming,
...toRefs(variables), ...toRefs(variables),
uiSettingStore, uiSettingStore,
trim trim
@ -300,6 +307,16 @@ export default defineComponent({
v-model:show={this.copyShowRef} v-model:show={this.copyShowRef}
onUpdateList={this.handleCopyUpdateList} onUpdateList={this.handleCopyUpdateList}
/> />
<NModal
v-model:show={this.setTimingDialogShowRef}
preset={'dialog'}
title={t('project.workflow.success')}
content={t('project.workflow.want_to_set_timing')}
positiveText={t('project.workflow.confirm')}
negativeText={t('project.workflow.cancel')}
maskClosable={false}
onPositiveClick={this.confirmToSetWorkflowTiming}
/>
</NSpace> </NSpace>
) )
} }

99
dolphinscheduler-ui/src/views/projects/workflow/definition/timing/use-table.ts

@ -75,6 +75,104 @@ export function useTable() {
]) ])
} }
const createTimingListTableColumns = (variables: any) => {
variables.columns = [
{
title: '#',
key: 'id',
...COLUMN_WIDTH_CONFIG['index'],
render: (row: any, index: number) => index + 1
},
{
title: t('project.workflow.start_time'),
key: 'startTime',
...COLUMN_WIDTH_CONFIG['timeZone'],
render: (row: any) => renderTime(row.startTime, row.timezoneId)
},
{
title: t('project.workflow.end_time'),
key: 'endTime',
...COLUMN_WIDTH_CONFIG['timeZone'],
render: (row: any) => renderTime(row.endTime, row.timezoneId)
},
{
title: t('project.workflow.crontab'),
key: 'crontab',
width: 140
},
{
title: t('project.workflow.status'),
key: 'releaseState',
...COLUMN_WIDTH_CONFIG['state'],
render: (row: any) => {
if (row.releaseState === 'ONLINE') {
return h(
NTag,
{ type: 'success', size: 'small' },
{
default: () => t('project.workflow.up_line')
}
)
} else {
return h(
NTag,
{ type: 'warning', size: 'small' },
{
default: () => t('project.workflow.down_line')
}
)
}
}
},
{
title: t('project.workflow.operation'),
key: 'operation',
...COLUMN_WIDTH_CONFIG['operation'](3),
render: (row: any) => {
return h(NSpace, null, {
default: () => [
h(
NTooltip,
{},
{
trigger: () =>
h(
NButton,
{
circle: true,
type:
row.releaseState === 'ONLINE' ? 'error' : 'warning',
size: 'small',
onClick: () => {
handleReleaseState(row)
}
},
{
icon: () =>
h(
row.releaseState === 'ONLINE'
? ArrowDownOutlined
: ArrowUpOutlined
)
}
),
default: () =>
row.releaseState === 'ONLINE'
? t('project.workflow.down_line')
: t('project.workflow.up_line')
}
),
]
})
}
}
]
if (variables.tableWidth) {
variables.tableWidth = calculateTableWidth(variables.columns)
}
}
const createColumns = (variables: any) => { const createColumns = (variables: any) => {
variables.columns = [ variables.columns = [
{ {
@ -326,6 +424,7 @@ export function useTable() {
return { return {
variables, variables,
createColumns, createColumns,
createTimingListTableColumns,
getTableData getTableData
} }
} }

14
dolphinscheduler-ui/src/views/projects/workflow/definition/use-table.ts

@ -63,7 +63,8 @@ export function useTable() {
timingShowRef: ref(false), timingShowRef: ref(false),
versionShowRef: ref(false), versionShowRef: ref(false),
copyShowRef: ref(false), copyShowRef: ref(false),
loadingRef: ref(false) loadingRef: ref(false),
setTimingDialogShowRef: ref(false)
}) })
const createColumns = (variables: any) => { const createColumns = (variables: any) => {
@ -351,8 +352,14 @@ export function useTable() {
| 'OFFLINE' | 'OFFLINE'
| 'ONLINE' | 'ONLINE'
} }
release(data, variables.projectCode, row.code).then(() => { release(data, variables.projectCode, row.code).then(() => {
window.$message.success(t('project.workflow.success')) if (data.releaseState === 'ONLINE') {
variables.setTimingDialogShowRef = true
variables.row = row
} else {
window.$message.success(t('project.workflow.success'))
}
getTableData({ getTableData({
pageSize: variables.pageSize, pageSize: variables.pageSize,
pageNo: variables.page, pageNo: variables.page,
@ -448,6 +455,7 @@ export function useTable() {
getTableData, getTableData,
batchDeleteWorkflow, batchDeleteWorkflow,
batchExportWorkflow, batchExportWorkflow,
batchCopyWorkflow batchCopyWorkflow,
gotoTimingManage
} }
} }

Loading…
Cancel
Save