Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@
* or submit itself to any jurisdiction.
*/

import { FilterInputModel } from '../../common/filters/FilterInputModel.js';
import { RawTextFilterModel } from '../../common/filters/RawTextFilterModel.js';

/**
* Model to handle the state of the Author Filter
*/
export class AuthorFilterModel extends FilterInputModel {
export class AuthorFilterModel extends RawTextFilterModel {
/**
* Constructor
*
Expand All @@ -32,7 +32,7 @@ export class AuthorFilterModel extends FilterInputModel {
* @return {boolean} true if '!Anonymous' is included in the raw filter string, false otherwise.
*/
isAnonymousExcluded() {
return this._raw.includes('!Anonymous');
return this._value.includes('!Anonymous');
}

/**
Expand All @@ -42,28 +42,13 @@ export class AuthorFilterModel extends FilterInputModel {
*/
toggleAnonymousFilter() {
if (this.isAnonymousExcluded()) {
this._raw = this._raw.split(',')
this._value = this._value.split(',')
.filter((author) => author.trim() !== '!Anonymous')
.join(',');
} else {
this._raw += super.isEmpty ? '!Anonymous' : ', !Anonymous';
this._value += super.isEmpty ? '!Anonymous' : ', !Anonymous';
}

this._value = this.valueFromRaw(this._raw);
this.notify();
}

/**
* Reset the filter to its default value and notify the observers.
*
* @return {void}
*/
clear() {
if (this.isEmpty) {
return;
}

super.reset();
this.notify();
}
}
33 changes: 13 additions & 20 deletions lib/public/components/Filters/LogsFilter/author/authorFilter.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,7 @@
import { h } from '/js/src/index.js';
import { iconX } from '/js/src/icons.js';
import { switchInput } from '../../../common/form/switchInput.js';

/**
* Returns a text input field that can be used to filter logs by author
*
* @param {AuthorFilterModel} authorFilterModel The author filter model object
* @returns {Component} A text box that allows the user to enter an author substring to match against all logs
*/
const authorFilterTextInput = (authorFilterModel) => h('input.w-40', {
type: 'text',
id: 'authorFilterText',
value: authorFilterModel.raw,
oninput: (e) => authorFilterModel.update(e.target.value),
});
import { rawTextFilter } from '../../common/filters/rawTextFilter.js';

/**
* Returns a button that can be used to reset the author filter.
Expand All @@ -36,7 +24,7 @@ const authorFilterTextInput = (authorFilterModel) => h('input.w-40', {
*/
const resetAuthorFilterButton = (authorFilterModel) => h(
'.btn.btn-pill.f7',
{ disabled: authorFilterModel.isEmpty, onclick: () => authorFilterModel.clear() },
{ disabled: authorFilterModel.isEmpty, onclick: () => authorFilterModel.reset() },
iconX(),
);

Expand All @@ -55,11 +43,16 @@ export const excludeAnonymousLogAuthorToggle = (authorFilterModel) => switchInpu
/**
* Returns a authorFilter component with text input, reset button, and anonymous exclusion button.
*
* @param {LogModel} logModel the log model object
* @returns {Component} the author filter component
* @param {LogsOverviewModel} logsOverviewModel the log overview model
* @param {FilteringModel} logsOverviewModel.filteringModel the runs overview model
* @return {Component} the filter component
*/
export const authorFilter = ({ authorFilter }) => h('.flex-row.items-center.g3', [
authorFilterTextInput(authorFilter),
resetAuthorFilterButton(authorFilter),
excludeAnonymousLogAuthorToggle(authorFilter),
export const authorFilter = ({ filteringModel }) => h('.flex-row.items-center.g3', [
rawTextFilter(filteringModel.get('authorFilter'), {
classes: ['w-40'],
id: 'authorFilterText',
value: filteringModel.get('authorFilter').raw,
}),
resetAuthorFilterButton(filteringModel.get('authorFilter')),
excludeAnonymousLogAuthorToggle(filteringModel.get('authorFilter')),
]);
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,44 @@
* granted to it by virtue of its status as an Intergovernmental Organization
* or submit itself to any jurisdiction.
*/
import { Observable } from '/js/src/index.js';

import { FilterModel } from '../FilterModel.js';

/**
* Model for a generic filter input
* Model that parses raw intput into a value
*/
export class FilterInputModel extends Observable {
export class ParsedInputFilterModel extends FilterModel {
/**
* Constructor
*
* @param {callback} parse function called to parse a value from a raw value
*/
constructor() {
constructor(parse) {
super();

this._parse = parse;
this._value = null;
this._raw = '';

this._visualChange$ = new Observable();
}

/**
* Define the current value of the filter
*
* @param {string} raw the raw value of the filter
* @override
* @return {void}
*/
update(raw) {
const previousValues = this.value;

this._value = this.valueFromRaw(raw);
this._raw = raw;
const value = this._parse(raw);

if (this.areValuesEquals(this.value, previousValues)) {
// Only raw value changed
this._visualChange$.notify();
} else {
if (!this.areValuesEquals(this._value, value)) {
this._value = value;
this.notify();
}
}

/**
* Reset the filter to its default value
*
* @return {void}
* @inheritdoc
*/
reset() {
this._value = null;
Expand Down Expand Up @@ -86,23 +82,10 @@ export class FilterInputModel extends Observable {
}

/**
* Returns the observable notified any time there is a visual change which has no impact on the actual filter value
*
* @return {Observable} the observable
*/
get visualChange$() {
return this._visualChange$;
}

/**
* Returns the processed value from raw input
*
* @param {string} raw the raw input value
* @return {*} the processed value
* @protected
* @inheritdoc
*/
valueFromRaw(raw) {
return raw.trim();
get normalized() {
return this.value;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { h } from '/js/src/index.js';
/**
* Returns a text filter component
*
* @param {FilterInputModel|TextTokensFilterModel} filterInputModel the model of the text filter
* @param {ParsedInputFilterModel|TextTokensFilterModel} filterInputModel the model of the text filter
* @param {Object} attributes the additional attributes to pass to the component, such as id and classes
* @return {Component} the filter component
*/
Expand Down
100 changes: 84 additions & 16 deletions lib/public/views/Logs/ActiveColumns/logsActiveColumns.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@ import { h } from '/js/src/index.js';
import { iconCommentSquare, iconPaperclip } from '/js/src/icons.js';

import { authorFilter } from '../../../components/Filters/LogsFilter/author/authorFilter.js';
import createdFilter from '../../../components/Filters/LogsFilter/created.js';
import runsFilter from '../../../components/Filters/LogsFilter/runs.js';
import { formatTimestamp } from '../../../utilities/formatting/formatTimestamp.js';
import { frontLink } from '../../../components/common/navigation/frontLink.js';
import { frontLinks } from '../../../components/common/navigation/frontLinks.js';
import { tagFilter } from '../../../components/Filters/common/filters/tagFilter.js';
import { formatRunsList } from '../../Runs/format/formatRunsList.js';
import { profiles } from '../../../components/common/table/profiles.js';
import { textFilter } from '../../../components/Filters/common/filters/textFilter.js';
import { environmentFilter } from '../../../components/Filters/LogsFilter/environments.js';
import { formatLhcFillsList } from '../../LhcFills/format/formatLhcFillsList.js';
import { lhcFillsFilter } from '../../../components/Filters/LogsFilter/lhcFill.js';
import { formatTagsList } from '../../Tags/format/formatTagsList.js';
import { rawTextFilter } from '../../../components/Filters/common/filters/rawTextFilter.js';
import { timeRangeFilter } from '../../../components/Filters/common/filters/timeRangeFilter.js';

/**
* A method to display a small and simple number/icon collection as a column
Expand Down Expand Up @@ -71,8 +68,16 @@ export const logsActiveColumns = {
visible: true,
sortable: true,
size: 'w-30',
filter: ({ titleFilter }) => textFilter(
titleFilter,

/**
* Title filter component
*
* @param {LogsOverviewModel} logOverviewModel the logs overview model
* @param {FilteringModel} logOverviewModel.filteringModel filtering model
* @return {Component} the filter component
*/
filter: ({ filteringModel }) => rawTextFilter(
filteringModel.get('titleFilter'),
{
id: 'titleFilterText',
class: 'w-75 mt1',
Expand All @@ -92,11 +97,19 @@ export const logsActiveColumns = {
name: 'Content',
visible: false,
size: 'w-10',
filter: ({ contentFilter }) => textFilter(
contentFilter,

/**
* Content filter component
*
* @param {LogsOverviewModel} logOverviewModel the logs overview model
* @param {FilteringModel} logOverviewModel.filteringModel filtering model
* @return {Component} the filter component
*/
filter: ({ filteringModel }) => rawTextFilter(
filteringModel.get('contentFilter'),
{
id: 'contentFilterText',
class: 'w-75 mt1',
classes: ['w-75', 'mt1'],
},
),
},
Expand All @@ -115,7 +128,15 @@ export const logsActiveColumns = {
sortable: true,
size: 'w-10',
format: (timestamp) => formatTimestamp(timestamp, false),
filter: createdFilter,

/**
* Created filter component
*
* @param {LogsOverviewModel} logOverviewModel the logs overview model
* @param {FilteringModel} logOverviewModel.filteringModel filtering model
* @return {Component} the filter component
*/
filter: ({ filteringModel }) => timeRangeFilter(filteringModel.get('created')),
profiles: {
embeded: {
format: (timestamp) => formatTimestamp(timestamp),
Expand All @@ -137,10 +158,12 @@ export const logsActiveColumns = {

/**
* Tag filter component
* @param {LogsOverviewModel} logsModel the log model
*
* @param {LogsOverviewModel} logOverviewModel the logs overview model
* @param {FilteringModel} logOverviewModel.filteringModel filtering model
* @return {Component} the filter component
*/
filter: (logsModel) => tagFilter(logsModel.listingTagsFilterModel),
filter: ({ filteringModel }) => tagFilter(filteringModel.get('tags')),
balloon: true,
profiles: [profiles.none, 'embeded'],
},
Expand All @@ -150,7 +173,22 @@ export const logsActiveColumns = {
sortable: true,
size: 'w-15',
format: formatRunsList,
filter: runsFilter,

/**
* Runs filter component
*
* @param {LogsOverviewModel} logOverviewModel the logs overview model
* @param {FilteringModel} logOverviewModel.filteringModel filtering model
* @return {Component} the filter component
*/
filter: ({ filteringModel }) => rawTextFilter(
filteringModel.get('run'),
{
id: 'runsFilterText',
classes: ['w-75', 'mt1'],
placeholder: 'e.g. 553203, 553221, ...',
},
),
balloon: true,
profiles: [profiles.none, 'embeded'],
},
Expand All @@ -167,7 +205,22 @@ export const logsActiveColumns = {
parameters: { environmentId: id },
}),
),
filter: environmentFilter,

/**
* Environment filter component
*
* @param {LogsOverviewModel} logOverviewModel the logs overview model
* @param {FilteringModel} logOverviewModel.filteringModel filtering model
* @return {Component} the filter component
*/
filter: ({ filteringModel }) => rawTextFilter(
filteringModel.get('environments'),
{
id: 'environmentFilterText',
classes: ['w-75', 'mt1'],
placeholder: 'e.g. Dxi029djX, TDI59So3d...',
},
),
balloon: true,
profiles: [profiles.none, 'embeded'],
},
Expand All @@ -177,7 +230,22 @@ export const logsActiveColumns = {
sortable: false,
size: 'w-10',
format: formatLhcFillsList,
filter: lhcFillsFilter,

/**
* LhcFills filter component
*
* @param {LogsOverviewModel} logOverviewModel the logs overview model
* @param {FilteringModel} logOverviewModel.filteringModel filtering model
* @return {Component} the filter component
*/
filter: ({ filteringModel }) => rawTextFilter(
filteringModel.get('lhcFills'),
{
id: 'lhcFillsFilterText',
classes: ['w-75', 'mt1'],
placeholder: 'e.g. 11392, 11383, 7625',
},
),
balloon: true,
profiles: [profiles.none, 'embeded'],
},
Expand Down
Loading
Loading