Skip to content

Commit

Permalink
Overviews for projects, dependencies, versions with filters (#170)
Browse files Browse the repository at this point in the history
* chore(ember/deps): add ember-template-imports and its prettier plugin

* refactor(ember): use ember-lifeline instead of runloop because of new linting rule

* feat: added backend filters for dependency

* feat: overviews for projects, depenencies and versions (with filters)

---------

Co-authored-by: Falk Neumann <[email protected]>
  • Loading branch information
c0rydoras and derrabauke authored Jan 22, 2024
1 parent a3768f0 commit a61b313
Show file tree
Hide file tree
Showing 74 changed files with 1,567 additions and 458 deletions.
27 changes: 27 additions & 0 deletions api/outdated/outdated/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from django_filters import FilterSet, UUIDFilter

from outdated.outdated import models


class VersionFilterSet(FilterSet):
dependency = UUIDFilter(
field_name="release_version__dependency",
)

class Meta:
model = models.Version
fields = ["dependency"]


class ProjectFilterSet(FilterSet):
dependency = UUIDFilter(
field_name="versioned_dependencies__release_version__dependency",
)

version = UUIDFilter(
field_name="versioned_dependencies",
)

class Meta:
model = models.Project
fields = ["dependency"]
4 changes: 3 additions & 1 deletion api/outdated/outdated/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet

from . import models, serializers
from . import filters, models, serializers
from .tracking import Tracker


Expand All @@ -17,6 +17,7 @@ class ProjectViewSet(ModelViewSet):
)

serializer_class = serializers.ProjectSerializer
filterset_class = filters.ProjectFilterSet

@action(detail=True, methods=["post"])
def sync(self, *args, **kwargs):
Expand All @@ -38,6 +39,7 @@ class ReleaseVersionViewSet(ModelViewSet):
class VersionViewSet(ModelViewSet):
queryset = models.Version.objects.all()
serializer_class = serializers.VersionSerializer
filterset_class = filters.VersionFilterSet


class DependencyViewSet(ModelViewSet):
Expand Down
22 changes: 20 additions & 2 deletions ember/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
'use strict';

module.exports = {
settings: {
'import/internal-regex': '^outdated/',
},
extends: ['@adfinis/eslint-config/ember-app'],
overrides: [
{
files: ['**/*.{js,ts}'],
rules: {
'ember/no-replace-test-comments': 'error',
},
},
{
files: ['**/*.gjs'],
parser: 'ember-eslint-parser',
plugins: ['ember'],
extends: ['plugin:ember/recommended-gjs'],
},
{
files: ['tests/**/*.{js,ts,gjs,gts}'],
rules: {
'ember/no-replace-test-comments': 'error',
},
},
],
};
3 changes: 2 additions & 1 deletion ember/.prettierrc.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use strict';

module.exports = {
plugins: ['prettier-plugin-ember-template-tag'],
overrides: [
{
files: '*.{js,ts}',
files: '*.{js,ts,gjs,gts}',
options: {
singleQuote: true,
},
Expand Down
1 change: 1 addition & 0 deletions ember/.stylelintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ module.exports = {
extends: ['stylelint-prettier/recommended', 'stylelint-config-standard-scss'],
rules: {
'scss/at-extend-no-missing-placeholder': null,
'selector-class-pattern': null,
},
};
3 changes: 1 addition & 2 deletions ember/.template-lintrc.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
'use strict';

module.exports = {
extends: ['recommended', 'ember-template-lint-plugin-prettier:recommended'],
plugins: ['ember-template-lint-plugin-prettier'],
extends: ['recommended'],
rules: {
'require-input-label': false,
'no-obsolete-elements': false,
Expand Down
69 changes: 69 additions & 0 deletions ember/app/components/cells.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { concat, fn } from '@ember/helper';
import { on } from '@ember/modifier';
import { LinkTo } from '@ember/routing';
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import hasNext from 'ember-composable-helpers/helpers/has-next';
import slice from 'ember-composable-helpers/helpers/slice';
import formatDate from 'ember-intl/helpers/format-date';
import ukTooltip from 'ember-uikit/modifiers/uk-tooltip';

import EOLForm from './eol-form';

export const ProjectCell = <template>
<LinkTo
class='uk-link-text'
@route='projects.detailed'
@model={{@project.id}}
>{{@project.name}}</LinkTo>
</template>;

export const DependencyCell = <template>
<LinkTo
class='uk-link-text'
@route='dependencies.detailed'
@model={{@dependency.id}}
>{{@dependency.name}}</LinkTo>
</template>;

export const VersionCell = <template>
<LinkTo
class='uk-link-text'
@route='versions.detailed'
@model={{@version.id}}
>{{@version.version}}</LinkTo>
</template>;

export const MaintainersCell = <template>
{{#each @maintainers as |m|}}
<span {{(modifier ukTooltip m.user.email pos='bottom')}}>
{{concat
m.user.username
(if (hasNext m (slice @maintainers)) ',' '')
}}</span>
{{/each}}
</template>;

export class EndOfLifeCell extends Component {
@tracked isEditing = false;

setIsEditing = (value) => {
this.isEditing = value;
};

<template>
<EOLForm
@version={{@version}}
@setIsEditing={{this.setIsEditing}}
@isEditing={{this.isEditing}}
/>
{{#let @version.releaseVersion.endOfLife as |eol|}}
<div
class='{{if eol "" "uk-text-italic"}} uk-link-text cursor-pointer'
tabindex='0'
...attributes
{{on 'click' (fn (mut this.isEditing) true)}}
>{{if eol (formatDate eol) 'undefined'}}</div>
{{/let}}
</template>
}
13 changes: 0 additions & 13 deletions ember/app/components/dependency-compact/template.hbs

This file was deleted.

102 changes: 102 additions & 0 deletions ember/app/components/dependency-detailed.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { service } from '@ember/service';
import Component from '@glimmer/component';
import UkIcon from 'ember-uikit/components/uk-icon';

import { VersionCell, ProjectCell, EndOfLifeCell } from './cells';
import Table from './table';

import { statusToClass, orderByEOL } from 'outdated/utils';

export default class DependencyDetailedComponent extends Component {
@service store;

get versions() {
return orderByEOL(
this.store
.peekAll('version')
.filter(
(version) =>
version.releaseVersion.dependency.id === this.args.dependency.id,
),
);
}

get projects() {
const getEOL = (project) =>
project.versionedDependencies.find(
(v) => v.releaseVersion.dependency.id === this.args.dependency.id,
).releaseVersion.endOfLife;
return orderByEOL(
this.store
.peekAll('project')
.filter(
(project) =>
project.versionedDependencies.filter(
(version) =>
version.releaseVersion.dependency.id ===
this.args.dependency.id,
).length,
),
getEOL,
);
}

get data() {
return orderByEOL(
this.versions.map((version) => ({
component: <template>
<tr class={{statusToClass version.status}}>{{yield}}</tr>
</template>,
values: {
version: <template><VersionCell @version={{version}} /></template>,
endOfLife: <template>
<EndOfLifeCell @version={{version}} />
</template>,
releaseDate: version.releaseDate,
},
})),
);
}

get projectData() {
return this.projects.map((project) => {
const version = project.versionedDependencies.find(
(version) =>
version.releaseVersion.dependency.id === this.args.dependency.id,
);
return {
component: <template>
<tr class={{statusToClass version.status}}>{{yield}}</tr>
</template>,
values: {
project: <template><ProjectCell @project={{project}} /></template>,
version: <template><VersionCell @version={{version}} /></template>,
},
};
});
}

<template>
<div class='detailed-header'>
<h1 data-test-project-name>
{{@dependency.name}}
</h1>

<a href='{{@dependency.url}}' data-test-dependency-link>
<UkIcon @icon='link' @ratio={{3}} />
</a>
</div>

<hr class='seperator' />

<Table @title='Versions' @data={{this.data}} as |t|>
<t.head />
<t.body />
</Table>

<Table @title='Used in' @data={{this.projectData}} as |t|>
<t.head />
<t.body />
</Table>
</template>
}
14 changes: 0 additions & 14 deletions ember/app/components/dependency-detailed/template.hbs

This file was deleted.

27 changes: 27 additions & 0 deletions ember/app/components/dependency-table.gjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Component from '@glimmer/component';

import { DependencyCell } from './cells';
import Table from './table';

export default class DependencyTable extends Component {
get data() {
return this.args.dependencies.map((dependency) => ({
values: {
name: <template>
<DependencyCell @dependency={{dependency}} />
</template>,
provider: dependency.provider,
},
}));
}
<template>
<Table
@data={{this.data}}
@fallback='Found no matching dependencies'
as |t|
>
<t.head />
<t.body />
</Table>
</template>
}
24 changes: 0 additions & 24 deletions ember/app/components/dependency-table/template.hbs

This file was deleted.

Loading

0 comments on commit a61b313

Please sign in to comment.