Skip to content
Snippets Groups Projects
Verified Commit 3ff648fc authored by Jonathan Weth's avatar Jonathan Weth :keyboard:
Browse files

Redesign about page with Vuetify

parent 4f3fd826
No related branches found
No related tags found
1 merge request!1095[Vue] About page
Pipeline #87876 failed
<template>
<div class="mt-4 mb-4">
<v-row align="stretch">
<v-col class="d-flex align-stretch">
<v-card class="d-flex flex-column">
<v-card-title>About AlekSIS</v-card-title>
<v-card-text>
<p>
This platform is powered by AlekSIS®, a web-based school information system (SIS) which can be used
to manage and/or publish organisational artifacts of educational institutions. AlekSIS is free software
and can be used by anyone.
</p>
<p>
AlekSIS® is a registered trademark of the AlekSIS open source project, represented by Teckids e.V.
</p>
</v-card-text>
<v-spacer></v-spacer>
<v-card-actions>
<v-btn text color="primary" href="https://aleksis.org/">Website of AlekSIS</v-btn>
<v-btn text color="primary" href="https://edugit.org/AlekSIS/">Source code</v-btn>
</v-card-actions>
</v-card>
</v-col>
<v-col class="d-flex align-stretch">
<v-card class="d-flex flex-column">
<v-card-title>Licence information</v-card-title>
<v-card-text>
<p>
The core and the official apps of AlekSIS are licenced under the EUPL, version 1.2 or later. For licence
information from third-party apps, if installed, refer to the respective components below. The
licences are marked like this:
</p>
<p>
<v-chip color="green" text-color="white">Free/Open Source Licence</v-chip>
<v-chip color="green" text-color="white">Other Licence</v-chip>
</p>
</v-card-text>
<v-spacer></v-spacer>
<v-card-actions>
<v-btn text color="primary" href="https://eupl.eu">Full licence text</v-btn>
<v-btn text color="primary"
href="https://joinup.ec.europa.eu/collection/eupl/guidelines-users-and-developers">
More information about the EUPL
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
<installed-apps-list/>
</div>
</template>
<script>
import InstalledAppsList from "./InstalledAppsList.vue";
export default {
name: "About",
components: {VCheckbox, InstalledAppsList}
}
</script>
<template>
<v-col cols="6" class="d-flex align-stretch">
<v-card :id="app.name" class="d-flex flex-column flex-grow-1">
<v-card-title>
{{ app.verboseName }}
<v-chip v-if="app.licence.flags.isFsfLibre" color="green" text-color="white" class="ml-4">Free Software</v-chip>
<v-chip v-else-if="app.licence.flags.isOsiApproved" color="green" text-color="white" class="ml-4">Open Source
</v-chip>
</v-card-title>
<v-card-subtitle>
{{ app.version }}
</v-card-subtitle>
<v-card-text>
<p v-if="app.copyrights.length !== 0">
<span v-for="(copyright, index) in app.copyrights" :key="index">
Copyright © {{ copyright.years }}
<a :href="'mailto:' + copyright.email">{{ copyright.name }}</a>
<br/>
</span>
</p>
<p v-if="app.licence">
This app is licenced under {{ app.licence.verboseName }}.
</p>
<div v-for="licence in app.licence.licences" class="mb-2" :key="licence.name">
<v-chip v-if="licence.isOsiApproved || licence.isFsfLibre" color="green" text-color="green" outlined
:href="licence.url">
{{ licence.name }}
</v-chip>
<v-chip v-else color="orange" text-color="orange" outlined :href="licence.url">
{{ licence.name }}
</v-chip>
</div>
</v-card-text>
<v-spacer></v-spacer>
<v-card-actions v-if="app.urls.length !== 0">
<v-btn
v-for="url in app.urls"
color="primary"
text
:href="url.url"
>
{{ url.name }}
</v-btn>
</v-card-actions>
</v-card>
</v-col>
</template>
<script>
export default {
name: "InstalledAppCard",
props: {
app: {
type: Object,
required: true,
},
},
}
</script>
<template>
<ApolloQuery
:query="require('./installedApps.graphql')"
>
<template v-slot="{ result: { error, data }, isLoading }">
<v-row>
<InstalledAppCard
v-for="app in data.installedApps"
:key="app.name"
:app="app"
/>
</v-row>
</template>
</ApolloQuery>
</template>
<script>
import InstalledAppCard from "./InstalledAppCard.vue";
export default {
name: "InstalledAppsList",
components: {InstalledAppCard}
}
</script>
{
installedApps {
name
verboseName
version
copyrights {
years
name
email
}
licence {
verboseName
flags {
isFsfLibre
isOsiApproved
}
licences {
isFsfLibre
isOsiApproved
name
url
}
}
urls {
name
url
}
}
}
......@@ -2,3 +2,7 @@ import '@mdi/font/css/materialdesignicons.css'
import "./util"
import "./app"
import About from "./components/about/About.vue";
window.router.addRoute({ path: "/about", component: About });
import graphene
from django.apps import apps
from graphene import ObjectType
from graphene_django import DjangoObjectType
from graphene_django.forms.mutation import DjangoModelFormMutation
from .forms import PersonForm
from .models import Group, Notification, Person
from .util.apps import AppConfig
from .util.core_helpers import get_app_module, get_app_packages, has_person
......@@ -27,6 +30,41 @@ class GroupType(DjangoObjectType):
model = Group
class AppURLType(ObjectType):
name = graphene.String(required=True)
url = graphene.String(required=True)
class CopyrightType(ObjectType):
years = graphene.String(required=True)
name = graphene.String(required=True)
email = graphene.String(required=True)
class LicenceFlagsType(ObjectType):
isFsfLibre = graphene.Boolean(required=True)
isOsiApproved = graphene.Boolean(required=True)
class SubLicenceType(ObjectType):
isDeprecatedLicenseId = graphene.Boolean(default_value=False)
isFsfLibre = graphene.Boolean(default_value=False)
isOsiApproved = graphene.Boolean(default_value=False)
licenseId = graphene.String(required=True)
name = graphene.String(required=True)
referenceNumber = graphene.Int(default_value=-1)
url = graphene.String()
class LicenceType(ObjectType):
verbose_name = graphene.String(required=True)
flags = graphene.Field(LicenceFlagsType, required=True)
licences = graphene.List(SubLicenceType)
class AppType(ObjectType):
copyrights = graphene.List(CopyrightType)
licence = graphene.Field(LicenceType)
name = graphene.String(required=True)
verbose_name = graphene.String(required=True)
version = graphene.String()
urls = graphene.List(AppURLType)
class PersonMutation(DjangoModelFormMutation):
person = graphene.Field(PersonType)
......@@ -59,6 +97,8 @@ class Query(graphene.ObjectType):
person_by_id = graphene.Field(PersonType, id=graphene.ID())
who_am_i = graphene.Field(PersonType)
installed_apps = graphene.List(AppType)
def resolve_notifications(root, info, **kwargs):
# FIXME do permission stuff
return Notification.objects.all()
......@@ -76,6 +116,8 @@ class Query(graphene.ObjectType):
else:
return None
def resolve_installed_apps(root, info, **kwargs):
return [app.get_dict() for app in apps.get_app_configs() if isinstance(a, AppConfig)]
class Mutation(graphene.ObjectType):
update_person = PersonMutation.Field()
......
......@@ -178,7 +178,7 @@ MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"debug_toolbar.middleware.DebugToolbarMiddleware",
# "debug_toolbar.middleware.DebugToolbarMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.http.ConditionalGetMiddleware",
"django.contrib.sites.middleware.CurrentSiteMiddleware",
......
{# -*- engine:django -*- #}
{% extends "core/base.html" %}
{% extends "core/vue_base.html" %}
{% load i18n %}
......@@ -7,121 +7,5 @@
{% block page_title %}{% blocktrans %}AlekSIS® – The Free School Information System{% endblocktrans %}{% endblock %}
{% block content %}
<div class="row">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">{% blocktrans %}About AlekSIS{% endblocktrans %}</span>
<p>
{% blocktrans %}
This platform is powered by AlekSIS®, a web-based school information system (SIS) which can be used
to manage and/or publish organisational artifacts of educational institutions. AlekSIS is free software and
can be used by anyone.
{% endblocktrans %}
</p>
<p>
{% blocktrans %}
AlekSIS® is a registered trademark of the AlekSIS open source project, represented by Teckids e.V.
{% endblocktrans %}
</p>
</div>
<div class="card-action">
<a class="" href="https://aleksis.org/">{% trans "Website of AlekSIS" %}</a>
<a class="" href="https://edugit.org/AlekSIS/">{% trans "Source code" %}</a>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col s12">
<div class="card">
<div class="card-content">
<span class="card-title">{% trans "Licence information" %}</span>
<p>
{% blocktrans %}
The core and the official apps of AlekSIS are licenced under the EUPL, version 1.2 or later. For licence
information from third-party apps, if installed, refer to the respective components below. The
licences are marked like this:
{% endblocktrans %}
</p>
<br/>
<p>
<span class="chip green white-text">{% trans "Free/Open Source Licence" %}</span>
<span class="chip orange white-text">{% trans "Other Licence" %}</span>
</p>
</div>
<div class="card-action">
<a href="https://eupl.eu">{% trans "Full licence text" %}</a>
<a href="https://joinup.ec.europa.eu/collection/eupl/guidelines-users-and-developers">{% trans "More information about the EUPL" %}</a>
</div>
</div>
</div>
</div>
<div class="row">
{% for app_config in app_configs %}
<div class="col s12 m12 l6">
<div class="card " id="{{ app_config.name }}">
<div class="card-content">
{% if app_config.get_licence.1.isFsfLibre %}
<span class="chip green white-text right">Free Software</span>
{% elif app_config.get_licence.1.isOsiApproved %}
<span class="chip green white-text right">Open Source</span>
{% endif %}
<span class="card-title">{{ app_config.get_name }} <small>{{ app_config.get_version }}</small></span>
{% if app_config.get_copyright %}
<p>
{% for holder in app_config.get_copyright %}
Copyright © {{ holder.0 }}
{% if holder.2 %}
<a href="mailto:{{ holder.2 }}">{{ holder.1 }}</a>
{% else %}
{{ holder.1 }}
{% endif %}
<br/>
{% endfor %}
</p>
<br/>
{% endif %}
{% if app_config.get_licence %}
{% with licence=app_config.get_licence %}
<p>
{% blocktrans with licence=licence.0 %}
This app is licenced under {{ licence }}.
{% endblocktrans %}
</p>
<br/>
<p>
{% for l in licence.2 %}
<a class="chip white-text {% if l.isOsiApproved or l.isFsfLibre %}green{% else %}orange{% endif %}"
href="{{ l.url }}">
{{ l.name }}
</a>
{% endfor %}
</p>
{% endwith %}
{% endif %}
</div>
{% if app_config.get_urls %}
<div class="card-action">
{% for url_name, url in app_config.get_urls.items %}
<a href="{{ url }}">{{ url_name }}</a>
{% endfor %}
</div>
{% endif %}
</div>
</div>
{% if forloop.counter|divisibleby:2 %}
</div>
<div class="row">
{% endif %}
{% endfor %}
</div>
<router-view></router-view>
{% endblock %}
......@@ -35,6 +35,10 @@ class AppConfig(django.apps.AppConfig):
# Getting an app ready means it should look at its config once
self.preference_updated(self)
def get_dict(self):
return {"name": self.name, "verbose_name": self.get_name(), "version": self.get_version(), "copyrights": self.get_copyright_dicts(), "licence": self.get_licence_dict(), "urls": self.get_urls_dict()}
def get_distribution_name(self):
"""Get distribution name of application package."""
if hasattr(self, "dist_name"):
......@@ -129,11 +133,26 @@ class AppConfig(django.apps.AppConfig):
return ("Unknown", [default_dict])
@classmethod
def get_licence_dict(cls):
"""Get licence information of application package."""
licence = cls.get_licence()
return {
"verbose_name": licence[0],
"flags": licence[1],
"licences": licence[2],
}
@classmethod
def get_urls(cls):
"""Get list of URLs for this application package."""
return getattr(cls, "urls", {})
# TODO Try getting from distribution if not set
@classmethod
def get_urls_dict(cls):
"""Get list of URLs for this application package."""
urls = cls.get_urls()
return [{"name": key, "url": value} for key, value in urls.items()]
@classmethod
def get_copyright(cls) -> Sequence[tuple[str, str, str]]:
"""Get copyright information tuples for application package."""
......@@ -155,6 +174,12 @@ class AppConfig(django.apps.AppConfig):
return copyrights_processed
# TODO Try getting from distribution if not set
@classmethod
def get_copyright_dicts(cls):
"""Get copyright information dictionaries for application package."""
infos = cls.get_copyright()
return [{"years": info[0], "name": info[1], "email": info[2] } for info in infos]
def preference_updated(
self,
sender: Any,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment