import { max, min } from 'date-fns';
import * as React from 'react';
import { PopupZLevel } from '../../helpers';
+import { InputSizeKeys } from '../../types';
import { LightLabel } from '../Text';
import { DatePicker } from './DatePicker';
className?: string;
clearButtonLabel: string;
fromLabel: string;
+ inputSize?: InputSizeKeys;
maxDate?: Date;
minDate?: Date;
onChange: (date: DateRange) => void;
alignEndDateCalandarRight,
clearButtonLabel,
fromLabel,
+ inputSize = 'full',
minDate,
maxDate,
separatorText,
minDate={minDate}
onChange={this.handleFromChange}
placeholder={fromLabel}
- size="full"
+ size={inputSize}
value={this.from}
valueFormatter={valueFormatter}
zLevel={zLevel}
minDate={minDate && this.from ? max([minDate, this.from]) : minDate ?? this.from}
onChange={this.handleToChange}
placeholder={toLabel}
- size="full"
+ size={inputSize}
value={this.to}
valueFormatter={valueFormatter}
zLevel={zLevel}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import { isSameMinute } from 'date-fns';
+import { ContentCell, Link, Note, Table, TableRow, TableRowInteractive } from 'design-system';
import { sortBy } from 'lodash';
import * as React from 'react';
-import Link from '../../../components/common/Link';
+import { useIntl } from 'react-intl';
import DateTimeFormatter from '../../../components/intl/DateTimeFormatter';
import { parseDate } from '../../../helpers/dates';
-import { translate } from '../../../helpers/l10n';
import { getRulesUrl } from '../../../helpers/urls';
import { ProfileChangelogEvent } from '../types';
import ChangesList from './ChangesList';
}
export default function Changelog(props: Props) {
+ const intl = useIntl();
+
let isEvenRow = false;
const sortedRows = sortBy(
props.events,
isEvenRow = !isEvenRow;
}
- const className = 'js-profile-changelog-event ' + (isEvenRow ? 'even' : 'odd');
-
return (
- <tr className={className} key={index}>
- <td className="thin nowrap">{!isBulkChange && <DateTimeFormatter date={event.date} />}</td>
+ <TableRowInteractive key={`${event.date}-${event.ruleKey}`}>
+ <ContentCell className="sw-whitespace-nowrap">
+ {!isBulkChange && <DateTimeFormatter date={event.date} />}
+ </ContentCell>
- <td className="thin nowrap">
- {!isBulkChange &&
- (event.authorName ? (
- <span>{event.authorName}</span>
- ) : (
- <span className="note">System</span>
- ))}
- </td>
+ <ContentCell className="sw-whitespace-nowrap sw-max-w-[120px]">
+ {!isBulkChange && (event.authorName ? event.authorName : <Note>System</Note>)}
+ </ContentCell>
- <td className="thin nowrap">
- {!isBulkChange && translate('quality_profiles.changelog', event.action)}
- </td>
+ <ContentCell className="sw-whitespace-nowrap">
+ {!isBulkChange &&
+ intl.formatMessage({ id: `quality_profiles.changelog.${event.action}` })}
+ </ContentCell>
- <td className="quality-profile-changelog-rule-cell">
+ <ContentCell>
<Link to={getRulesUrl({ rule_key: event.ruleKey })}>{event.ruleName}</Link>
- </td>
+ </ContentCell>
- <td>{event.params && <ChangesList changes={event.params} />}</td>
- </tr>
+ <ContentCell>{event.params && <ChangesList changes={event.params} />}</ContentCell>
+ </TableRowInteractive>
);
});
return (
- <table className="data zebra-hover">
- <thead>
- <tr>
- <th className="thin nowrap">{translate('date')}</th>
- <th className="thin nowrap">{translate('user')}</th>
- <th className="thin nowrap">{translate('action')}</th>
- <th>{translate('rule')}</th>
- <th>{translate('parameters')}</th>
- </tr>
- </thead>
- <tbody>{rows}</tbody>
- </table>
+ <Table
+ columnCount={5}
+ header={
+ <TableRow>
+ <ContentCell>{intl.formatMessage({ id: 'date' })}</ContentCell>
+ <ContentCell>{intl.formatMessage({ id: 'user' })}</ContentCell>
+ <ContentCell>{intl.formatMessage({ id: 'action' })}</ContentCell>
+ <ContentCell>{intl.formatMessage({ id: 'rule' })}</ContentCell>
+ <ContentCell>{intl.formatMessage({ id: 'updates' })}</ContentCell>
+ </TableRow>
+ }
+ >
+ {rows}
+ </Table>
);
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { ButtonSecondary, Spinner } from 'design-system';
import * as React from 'react';
import { ChangelogResponse, getProfileChangelog } from '../../../api/quality-profiles';
import { Location, Router, withRouter } from '../../../components/hoc/withRouter';
-import Spinner from '../../../components/ui/Spinner';
import { parseDate, toISO8601WithOffsetString } from '../../../helpers/dates';
import { translate } from '../../../helpers/l10n';
import { withQualityProfilesContext } from '../qualityProfilesContext';
this.state.events.length < this.state.total;
return (
- <div className="boxed-group boxed-group-inner js-profile-changelog">
- <div className="spacer-bottom">
+ <div>
+ <div className="sw-mb-2 sw-flex sw-gap-4 sw-items-center">
<ChangelogSearch
dateRange={{
from: query.since ? parseDate(query.since) : undefined,
onDateRangeChange={this.handleDateRangeChange}
onReset={this.handleReset}
/>
- <Spinner loading={this.state.loading} className="spacer-left" />
+ <Spinner loading={this.state.loading} />
</div>
{this.state.events != null && this.state.events.length === 0 && <ChangelogEmpty />}
)}
{shouldDisplayFooter && (
- <footer className="text-center spacer-top small">
- <a href="#" onClick={this.loadMore.bind(this)}>
+ <footer className="sw-text-center sw-mt-2">
+ <ButtonSecondary onClick={this.loadMore.bind(this)}>
{translate('show_more')}
- </a>
+ </ButtonSecondary>
</footer>
)}
</div>
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { translate } from '../../../helpers/l10n';
+import { useIntl } from 'react-intl';
export default function ChangelogEmpty() {
- return <div className="big-spacer-top">{translate('no_results')}</div>;
+ const intl = useIntl();
+
+ return <div className="sw-mt-6">{intl.formatMessage({ id: 'no_results' })}</div>;
}
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+import { ButtonSecondary, DateRangePicker } from 'design-system';
import * as React from 'react';
-import { Button } from '../../../components/controls/buttons';
-import DateRangeInput from '../../../components/controls/DateRangeInput';
-import { translate } from '../../../helpers/l10n';
+import { useIntl } from 'react-intl';
interface ChangelogSearchProps {
dateRange: { from?: Date; to?: Date } | undefined;
export default function ChangelogSearch(props: ChangelogSearchProps) {
const { dateRange } = props;
+
+ const intl = useIntl();
+
return (
- <div className="display-flex-end" id="quality-profile-changelog-form">
- <DateRangeInput onChange={props.onDateRangeChange} value={dateRange} />
- <Button className="spacer-left text-top" onClick={props.onReset}>
- {translate('reset_verb')}
- </Button>
+ <div className="sw-flex sw-gap-2">
+ <DateRangePicker
+ clearButtonLabel={intl.formatMessage({ id: 'clear' })}
+ fromLabel={intl.formatMessage({ id: 'start_date' })}
+ inputSize="small"
+ separatorText={intl.formatMessage({ id: 'to' })}
+ toLabel={intl.formatMessage({ id: 'end_date' })}
+ onChange={props.onDateRangeChange}
+ value={dateRange}
+ />
+ <ButtonSecondary className="sw-ml-2 sw-align-top" onClick={props.onReset}>
+ {intl.formatMessage({ id: 'reset_verb' })}
+ </ButtonSecondary>
</div>
);
}
};
return (
- <ul>
+ <ul className="sw-flex sw-flex-col sw-gap-1">
{Object.keys(changes).map((key) => (
<li key={key}>
{key === 'severity' ? (
export default function ParameterChange({ name, value }: Props) {
return (
- <div className="quality-profile-changelog-parameter">
+ <p className="sw-break-words">
{value == null
? translateWithParameters(
'quality_profiles.changelog.parameter_reset_to_default_value',
name,
)
: translateWithParameters('quality_profiles.parameter_set_to', name, value)}
- </div>
+ </p>
);
}
row: byRole('row'),
link: byRole('link'),
emptyPage: byText('no_results'),
- showMore: byRole('link', { name: 'show_more' }),
+ showMore: byRole('button', { name: 'show_more' }),
startDate: byRole('textbox', { name: 'start_date' }),
endDate: byRole('textbox', { name: 'end_date' }),
reset: byRole('button', { name: 'reset_verb' }),
<DateFromNow date={profile.lastUsed} />
</div>
- <div>
- <Link
- className="it__quality-profiles__changelog"
- to={getProfileChangelogPath(profile.name, profile.language)}
- >
- {translate('see_changelog')}
- </Link>
- </div>
+ {!isChangeLogPage && (
+ <div>
+ <Link
+ className="it__quality-profiles__changelog"
+ to={getProfileChangelogPath(profile.name, profile.language)}
+ >
+ {translate('see_changelog')}
+ </Link>
+ </div>
+ )}
</>
)}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-.quality-profile-changelog-rule-cell {
- line-height: 1.5;
-}
-
-.quality-profile-changelog-parameter {
- max-width: 270px;
- word-break: break-word;
-}
-
#create-profile-form .radio-card {
width: 244px;
background-color: var(--neutral50);
unresolved=Unresolved
updated=Updated
updated_on=Updated on
+updates=Updates
update_verb=Update
updating=Updating
unselected=Unselected