Skip to content

Commit

Permalink
show config for every app run
Browse files Browse the repository at this point in the history
  • Loading branch information
karanh37 committed Jan 29, 2025
1 parent 995cff8 commit 96f96c8
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 50 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ const AppDetails = () => {
{appData && (
<AppSchedule
appData={appData}
jsonSchema={jsonSchema as RJSFSchema}
loading={{
isRunLoading: loadingState.isRunLoading,
isDeployLoading: loadingState.isDeployLoading,
Expand Down Expand Up @@ -405,7 +406,10 @@ const AppDetails = () => {
key: ApplicationTabs.RECENT_RUNS,
children: (
<div className="p-lg">
<AppRunsHistory appData={appData} />
<AppRunsHistory
appData={appData}
jsonSchema={jsonSchema as RJSFSchema}
/>
</div>
),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { Button, Col, Row, Typography } from 'antd';
import validator from '@rjsf/validator-ajv8';
import { Button, Col, Modal, Row, Space, Typography } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import { AxiosError } from 'axios';
import { isNull } from 'lodash';
import { isNull, noop } from 'lodash';
import React, {
forwardRef,
useCallback,
Expand All @@ -31,8 +32,12 @@ import {
} from '../../../../constants/constants';
import { GlobalSettingOptions } from '../../../../constants/GlobalSettings.constants';
import { useWebSocketConnector } from '../../../../context/WebSocketProvider/WebSocketProvider';
import { ServiceCategory } from '../../../../enums/service.enum';
import { AppType } from '../../../../generated/entity/applications/app';
import { Status } from '../../../../generated/entity/applications/appRunRecord';
import {
AppRunRecord,
Status,
} from '../../../../generated/entity/applications/appRunRecord';
import {
PipelineState,
PipelineStatus,
Expand All @@ -51,24 +56,33 @@ import {
getEpochMillisForPastDays,
getIntervalInMilliseconds,
} from '../../../../utils/date-time/DateTimeUtils';
import { getEntityName } from '../../../../utils/EntityUtils';
import { getLogsViewerPath } from '../../../../utils/RouterUtils';
import { showErrorToast } from '../../../../utils/ToastUtils';
import ErrorPlaceHolder from '../../../common/ErrorWithPlaceholder/ErrorPlaceHolder';
import FormBuilder from '../../../common/FormBuilder/FormBuilder';
import NextPrevious from '../../../common/NextPrevious/NextPrevious';
import { PagingHandlerParams } from '../../../common/NextPrevious/NextPrevious.interface';
import StatusBadge from '../../../common/StatusBadge/StatusBadge.component';
import { StatusType } from '../../../common/StatusBadge/StatusBadge.interface';
import Table from '../../../common/Table/Table';
import StopScheduleModal from '../../../Modals/StopScheduleRun/StopScheduleRunModal';
import applicationsClassBase from '../AppDetails/ApplicationsClassBase';
import AppLogsViewer from '../AppLogsViewer/AppLogsViewer.component';
import './app-run-history.less';
import {
AppRunRecordWithId,
AppRunsHistoryProps,
} from './AppRunsHistory.interface';

const AppRunsHistory = forwardRef(
(
{ appData, maxRecords, showPagination = true }: AppRunsHistoryProps,
{
appData,
maxRecords,
jsonSchema,
showPagination = true,
}: AppRunsHistoryProps,
ref
) => {
const { socket } = useWebSocketConnector();
Expand All @@ -80,6 +94,17 @@ const AppRunsHistory = forwardRef(
>([]);
const [expandedRowKeys, setExpandedRowKeys] = useState<string[]>([]);
const [isStopModalOpen, setIsStopModalOpen] = useState<boolean>(false);
const [showConfigModal, setShowConfigModal] = useState<boolean>(false);
const [appRunRecordConfig, setAppRunRecordConfig] = useState<
AppRunRecord['config']
>({});
const UiSchema = {
...applicationsClassBase.getJSONUISchema(),
'ui:submitButtonProps': {
showButton: false,
buttonText: 'submit',
},
};

const {
currentPage,
Expand Down Expand Up @@ -132,6 +157,11 @@ const AppRunsHistory = forwardRef(
return false;
}, []);

const showAppRunConfig = (record: AppRunRecordWithId) => {
setShowConfigModal(true);
setAppRunRecordConfig(record.config ?? {});
};

const getActionButton = useCallback(
(record: AppRunRecordWithId, index: number) => {
if (
Expand All @@ -149,6 +179,14 @@ const AppRunsHistory = forwardRef(
onClick={() => handleRowExpandable(record.id)}>
{t('label.log-plural')}
</Button>
<Button
className="m-l-xs p-0"
data-testid="app-historical-config"
size="small"
type="link"
onClick={() => showAppRunConfig(record)}>
{t('label.config')}
</Button>
{/* For status running or activewitherror and supportsInterrupt is true, show stop button */}
{(record.status === Status.Running ||
record.status === Status.ActiveError) &&
Expand Down Expand Up @@ -214,7 +252,7 @@ const AppRunsHistory = forwardRef(
return record.status ? (
<StatusBadge
dataTestId="pipeline-status"
label={STATUS_LABEL[record.status]}
label={STATUS_LABEL[record.status as keyof typeof STATUS_LABEL]}
status={status}
/>
) : (
Expand Down Expand Up @@ -408,6 +446,52 @@ const AppRunsHistory = forwardRef(
}}
/>
)}
<Modal
centered
destroyOnClose
bodyStyle={{
maxHeight: 700,
overflowY: 'scroll',
}}
className="app-config-modal"
closable={false}
data-testid="edit-table-type-property-modal"
footer={
<Space className="w-full justify-end">
<Button
data-testid="selectable-list-update-btn"
type="primary"
onClick={() => setShowConfigModal(false)}>
{t('label.close')}
</Button>
</Space>
}
maskClosable={false}
open={showConfigModal}
title={
<Typography.Text>
{t('label.entity-configuration', {
entity: getEntityName(appData) ?? t('label.application'),
})}
</Typography.Text>
}
width={800}>
<FormBuilder
hideCancelButton
readonly
useSelectWidget
cancelText={t('label.back')}
formData={appRunRecordConfig}
isLoading={false}
okText={t('label.submit')}
schema={jsonSchema}
serviceCategory={ServiceCategory.DASHBOARD_SERVICES}
uiSchema={UiSchema}
validator={validator}
onCancel={noop}
onSubmit={noop}
/>
</Modal>
</>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
* limitations under the License.
*/

import { RJSFSchema } from '@rjsf/utils';
import { App } from '../../../../generated/entity/applications/app';
import { AppRunRecord } from '../../../../generated/entity/applications/appRunRecord';

Expand All @@ -26,4 +27,5 @@ export interface AppRunsHistoryProps {
maxRecords?: number;
appData?: App;
showPagination?: boolean;
jsonSchema: RJSFSchema;
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,18 @@ const mockGetApplicationRuns = jest.fn().mockReturnValue({
const mockShowErrorToast = jest.fn();
const mockPush = jest.fn();

jest.mock('../../../../utils/EntityUtils', () => ({
getEntityName: jest.fn().mockReturnValue('username'),
}));

jest.mock('../../../common/FormBuilder/FormBuilder', () =>
jest
.fn()
.mockImplementation(({ onSubmit }) => (
<button onClick={onSubmit}>Configure Save</button>
))
);

jest.mock('../../../../hooks/paging/usePaging', () => ({
usePaging: jest.fn().mockReturnValue({
currentPage: 8,
Expand Down Expand Up @@ -132,6 +144,7 @@ const mockProps1 = {
appData: mockApplicationData,
maxRecords: 10,
showPagination: true,
jsonSchema: {},
};

const mockProps2 = {
Expand Down Expand Up @@ -256,7 +269,7 @@ describe('AppRunsHistory component', () => {
});

it('checking behaviour of component when no prop is passed', async () => {
render(<AppRunsHistory />);
render(<AppRunsHistory jsonSchema={{}} />);
await waitForElementToBeRemoved(() => screen.getByText('TableLoader'));

expect(screen.getByText('--')).toBeInTheDocument();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright 2025 Collate.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.app-config-modal {
.ant-modal-body {
padding-top: 0;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { AppScheduleProps } from './AppScheduleProps.interface';
const AppSchedule = ({
appData,
loading: { isRunLoading, isDeployLoading },
jsonSchema,
onSave,
onDemandTrigger,
onDeployTrigger,
Expand Down Expand Up @@ -127,6 +128,7 @@ const AppSchedule = ({
return (
<AppRunsHistory
appData={appData}
jsonSchema={jsonSchema}
maxRecords={1}
ref={appRunsHistoryRef}
showPagination={false}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ const mockProps1 = {
isRunLoading: false,
isDeployLoading: false,
},
jsonSchema: {},
onSave: mockOnSave,
onDemandTrigger: mockOnDemandTrigger,
onDeployTrigger: mockOnDeployTrigger,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RJSFSchema } from '@rjsf/utils';
import { App } from '../../../../generated/entity/applications/app';

export interface AppScheduleProps {
Expand All @@ -18,6 +19,7 @@ export interface AppScheduleProps {
isRunLoading: boolean;
isDeployLoading: boolean;
};
jsonSchema: RJSFSchema;
onSave: (cron: string) => Promise<void>;
onDemandTrigger: () => Promise<void>;
onDeployTrigger: () => Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const ObjectFieldTemplate: FunctionComponent<ObjectFieldTemplateProps> =

const fieldElement = (
<Fragment>
<Space className="w-full justify-between">
<Space className="w-full justify-between header-title-wrapper">
<label
className={classNames('control-label', {
'font-medium text-base-color text-md':
Expand Down Expand Up @@ -104,23 +104,21 @@ export const ObjectFieldTemplate: FunctionComponent<ObjectFieldTemplateProps> =
</div>
))}
{!isEmpty(advancedProperties) && (
<>
<Collapse
className="advanced-properties-collapse"
expandIconPosition="end">
<Panel header={`${title} ${t('label.advanced-config')}`} key="1">
{advancedProperties.map((element, index) => (
<div
className={classNames('property-wrapper', {
'additional-fields': schema.additionalProperties,
})}
key={`${element.content.key}-${index}`}>
{element.content}
</div>
))}
</Panel>
</Collapse>
</>
<Collapse
className="advanced-properties-collapse"
expandIconPosition="end">
<Panel header={`${title} ${t('label.advanced-config')}`} key="1">
{advancedProperties.map((element, index) => (
<div
className={classNames('property-wrapper', {
'additional-fields': schema.additionalProperties,
})}
key={`${element.content.key}-${index}`}>
{element.content}
</div>
))}
</Panel>
</Collapse>
)}
</Fragment>
);
Expand Down
Loading

0 comments on commit 96f96c8

Please sign in to comment.