Skip to content
Snippets Groups Projects
Commit d57fdb5e authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

wip - contract table

parent 2d0c2f4e
Branches
No related tags found
No related merge requests found
......@@ -2,7 +2,10 @@ from django.contrib import admin
from shared.admin import MarkdownxGuardedModelAdmin
from .forms import ContractAdminForm, SigneeAdminForm
from .forms import (
ContractAdminForm,
SigneeAdminForm,
)
from .models import (
Contract,
Contractee,
......
from django import forms
from webpack_loader.loader import WebpackLoader
from .models import Contractee, Signee
class ContractAdminForm(forms.ModelForm):
class Media:
......
from django.conf import settings
from django.db import models
from django_countries.fields import CountryField
from colorfield.fields import ColorField
from markdownx.models import MarkdownxField
from shared.models import NameStrMixin
......@@ -84,8 +85,7 @@ class Signee(models.Model):
verbose_name="Organizační složka",
)
color = models.CharField(
max_length=6, # e.g. "ffffff"
color = ColorField(
blank=True,
null=True,
verbose_name="Barva",
......@@ -107,6 +107,14 @@ class Signee(models.Model):
if self.department is not None:
result += f", {self.department}"
representative_names = []
for representative in self.representatives.all():
representative_names.append(representative.name)
if len(representative_names) != 0:
result += " - zástupci " + ", ".join(representative_names)
return result
......@@ -187,9 +195,7 @@ class Contractee(models.Model):
verbose_name="Organizační složka",
)
# TODO: Input validation
color = models.CharField(
max_length=6, # e.g. "ffffff"
color = ColorField(
blank=True,
null=True,
verbose_name="Barva",
......@@ -205,6 +211,14 @@ class Contractee(models.Model):
if self.department is not None:
result += f", {self.department}"
representative_names = []
for representative in self.representatives.all():
representative_names.append(representative.name)
if len(representative_names) != 0:
result += " - zástupci " + ", ".join(representative_names)
return result
......@@ -496,7 +510,12 @@ class ContracteeSignature(models.Model):
verbose_name_plural = "Podpisy našich smluvních stran"
def __str__(self) -> str:
representatives = ", ".join(self.contractee.representatives)
representative_names = []
for representative in self.contractee.representatives.all():
representative_names.append(representative.name)
representatives = ", ".join(representative_names)
result = self.contractee.name
if len(representatives) != 0:
......@@ -531,7 +550,12 @@ class SigneeSignature(models.Model):
verbose_name_plural = "Podpisy ostatních smluvních stran"
def __str__(self) -> str:
representatives = ", ".join(self.signee.representatives)
representative_names = []
for representative in self.signee.representatives.all():
representative_names.append(representative.name)
representatives = ", ".join(representative_names)
result = self.signee.name
if len(representatives) != 0:
......
{% extends "shared/includes/base.html" %}
{% block content %}
<h1 class="head-alt-lg mb-10">{{ title }}</h1>
<table class="table table--striped table--bordered">
<thead>
<tr>
<td>Identifikátor</td>
<td>Typ</td>
<td>Právní stav</td>
<td>Účinná od</td>
<td>Platná do</td>
<td>Naše smluvní strana</td>
<td>Ostatní smluvní strany</td>
</tr>
</thead>
<tbody>
{% for contract in page %}
<tr>
<td>{{ contract.identifier }}</td>
<td>{{ contract.get_type_display }}</td>
<td>{{ contract.get_legal_state_display }}</td>
<td>{{ contract.valid_start_date }}</td>
<td>{{ contract.valid_end_date }}</td>
<td></td>
<td></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
from django.conf import settings
from django.shortcuts import render
from django.core.paginator import Paginator
from .models import Contract
# Create your views here.
def index(request):
contracts = Contract.objects.all()
paginator = Paginator(contracts, 25)
page = paginator.get_page(
request.GET.get('page')
)
return render(
request,
"contracts/index.html",
{
"site_url": settings.SITE_URL,
"user": request.user,
"title": "Title",
"title": "Seznam smluv",
"description": "Description",
"page": page,
}
)
{% load static %}
{% load render_bundle from webpack_loader %}
<!DOCTYPE html>
<html lang="cs" class="h-full">
<head>
<meta encoding="utf-8">
<link
rel="stylesheet"
type="text/css"
href="{% static "shared/style.css" %}"
>
<link
rel="stylesheet"
href="https://gfonts.pirati.cz/css2?family=Bebas+Neue&family=Roboto+Condensed:ital,wght@0,300;0,400;0,700;1,300;1,400;1,700&display=swap"
>
<link
rel="stylesheet"
type="text/css"
href="{% static "shared/fonts/pirati-ui/style.css" %}"
>
<title>{% block current_page %}{% endblock %}</title>
{% render_bundle "base" %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{% extends "oidc/base.html" %}
{% block content %}
<a href="{% url "oidc_authentication_init" %}">Přihlásit se</a>
{% endblock %}
......@@ -3,6 +3,4 @@ from django.urls import path
from . import views
app_name = "oidc"
urlpatterns = [
path("login", views.login, name="login"),
]
urlpatterns = []
from django.shortcuts import render
def login(request):
return render(
request,
"oidc/login.html",
)
......@@ -14,7 +14,9 @@
"dependencies": {
"css-loader": "^6.7.3",
"jquery": "^3.6.3",
"style-loader": "^3.3.1",
"tailwindcss": "^3.2.4",
"tippy.js": "^6.3.7",
"vue": "v2-latest",
"webpack": "^5.75.0",
"webpack-bundle-tracker": "^1.8.0",
......
......@@ -35,6 +35,7 @@ SECRET_KEY = env.str("SECRET_KEY")
ALLOWED_HOSTS = []
STATIC_ROOT = os.path.join(BASE_DIR, "staticfiles")
MEDIA_ROOT = os.path.join(BASE_DIR, "media")
SITE_URL = env.str("SITE_URL")
......@@ -48,6 +49,7 @@ INSTALLED_APPS = [
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"colorfield",
"guardian",
"markdownx",
"pirates",
......@@ -129,9 +131,9 @@ AUTHENTICATION_BACKENDS = (
"guardian.backends.ObjectPermissionBackend",
)
LOGIN_URL = "/oidc/login"
LOGIN_URL = "/"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/oidc/login"
LOGOUT_REDIRECT_URL = "/"
OIDC_RP_CLIENT_ID = env.str("OIDC_RP_CLIENT_ID")
OIDC_RP_CLIENT_SECRET = env.str("OIDC_RP_CLIENT_SECRET")
......
......@@ -4,6 +4,7 @@ psycopg2-binary==2.9.5
django-webpack-loader==1.8.0
nodeenv==1.7.0
pirates==0.6.0
django-colorfield==0.8.0
django-markdownx==4.0.0b1
django-environ==0.9.0
django-http-exceptions==1.4.0
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
width="560"
height="560"
fill="#ffffff"
id="svg15">
<metadata
id="metadata19">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Abstract user icon</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<title
id="title2">Abstract user icon</title>
<defs
id="defs7">
<clipPath
id="circular-border">
<circle
cx="300"
cy="300"
r="250"
id="circle4" />
</clipPath>
</defs>
<circle
cx="280"
cy="280"
fill="#000000"
id="circle9"
r="280"
style="fill:#f5f5f5;fill-opacity:1" />
<circle
cx="280"
cy="210"
r="100"
id="circle11"
style="fill:#262626;fill-opacity:1" />
<circle
cx="300"
cy="550"
r="190"
clip-path="url(#circular-border)"
id="circle13"
transform="translate(-20,-20)"
style="fill:#262626;fill-opacity:1" />
</svg>
......@@ -6,20 +6,20 @@
<head>
<meta charset="utf-8">
<meta name="title" content="{{ title }}">
<meta name="title" content="{{ title }} | Registr smluv Pirátské strany">
<meta name="description" content="{{ description }}">
{% comment %}Open Graph / Facebook{% endcomment %}
<meta property="og:type" content="website">
<meta property="og:url" content="{{ site_url }}">
<meta property="og:title" content="{{ title }}">
<meta property="og:title" content="{{ title }} | Registr smluv Pirátské strany">
<meta property="og:description" content="{{ description }}">
{% comment %}<meta property="og:image" content="">{% endcomment %}
{% comment %}Twitter{% endcomment %}
<meta property="twitter:card" content="app">
<meta property="twitter:url" content="{{ site_url }}">
<meta property="twitter:title" content="{{ title }}">
<meta property="twitter:title" content="{{ title }} | Registr smluv Pirátské strany">
<meta property="twitter:description" content="{{ description }}">
{% comment %}<meta property="twitter:image" content="">{% endcomment %}
......@@ -43,76 +43,82 @@
{% render_bundle "shared" %}
{% render_bundle "base" %}
<title>{{ title }}</title>
<title>{{ title }} | Registr smluv Pirátské strany</title>
</head>
<body>
<header>
<nav class="navbar navbar--simple __js-root">
<ui-app inline-template>
<ui-navbar inline-template>
<div>
<div class="container container--default navbar__content" :class="{'navbar__content--initialized': true}">
<div class="navbar__brand my-4 flex items-center lg:pr-8 lg:my-0">
<a href="/">
<img src="https://styleguide.pirati.cz/2.11.x/images/logo-round-white.svg" class="w-8" />
</a>
<a href="/" class="pl-4 font-bold text-xl lg:border-r lg:border-grey-300 lg:pr-8">Registr smluv</a>
</div>
<div class="navbar__menutoggle my-4 flex justify-end lg:hidden">
<a href="#" @click="show = !show" class="no-underline hover:no-underline">
<i class="ico--menu text-3xl"></i>
</a>
</div>
<div v-if="show || isLgScreenSize" class="navbar__main navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto">
<ul class="navbar-menu text-white">
<li class="navbar-menu__item">
<a href="#TODO" data-href="#TODO" class="navbar-menu__link">Všechny smlouvy</a>
</li>
<nav class="navbar navbar--simple __js-root">
<ui-app inline-template>
<ui-navbar inline-template>
<div>
<div class="container container--default navbar__content" :class="{'navbar__content--initialized': true}">
<div class="navbar__brand my-4 flex items-center lg:pr-8 lg:my-0">
<a href="/">
<img src="https://styleguide.pirati.cz/2.11.x/images/logo-round-white.svg" class="w-8" />
</a>
<a href="/" class="pl-4 font-bold text-xl hover:no-underline lg:border-r lg:border-grey-300 lg:pr-8">Registr smluv</a>
</div>
<div class="navbar__menutoggle my-4 flex justify-end lg:hidden">
<a href="#" @click="show = !show" class="no-underline hover:no-underline">
<i class="ico--menu text-3xl"></i>
</a>
</div>
<div v-if="show || isLgScreenSize" class="navbar__main navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto">
<ul class="navbar-menu text-white">
<li class="navbar-menu__item">
<a href="{% url "contracts:index" %}" data-href="{% url "contracts:index" %}" class="navbar-menu__link">Všechny smlouvy</a>
</li>
<li class="navbar-menu__item">
<a href="#TODO" data-href="#TODO" class="navbar-menu__link">Hledání</a>
</li>
{% if user.is_staff %}
<li class="navbar-menu__item">
<a href="#TODO" data-href="#TODO" class="navbar-menu__link">Hledání</a>
<a href="{% url "admin:index" %}" data-href="{% url "admin:index" %}" class="navbar-menu__link">Administrace</a>
</li>
</ul>
</div>
<div v-if="show || isLgScreenSize" class="navbar__actions navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto self-start flex flex-col sm:flex-row lg:flex-col sm:space-x-4 space-y-2 sm:space-y-0 lg:space-y-2 xl:flex-row xl:space-x-2 xl:space-y-0">
{% if user %}
<div class="flex items-center space-x-4">
<span class="head-heavy-2xs">{{ user.get_username }}</span>
<div class="avatar avatar--2xs">
<img
src="https://randomuser.me/api/portraits/women/83.jpg"
alt="Tvůj profilový obrázek"
>
</div>
<form action="{% url "oidc_logout" %}" method="POST">
{% csrf_token %}
<button
class="text-grey-200 hover:text-white"
type="submit"
><i class="ico--log-out"></i></button>
</form>
</div>
{% else %}
<a
class="btn btn--white btn--hoveractive cursor-pointer"
href="{% url "oidc:login" %}"
>
<div class="btn__body">Přihlásit se</div>
</a>
{% endif %}
</div>
</ul>
</div>
<div v-if="show || isLgScreenSize" class="navbar__actions navbar__section navbar__section--expandable container-padding--zero lg:container-padding--auto self-start flex flex-col sm:flex-row lg:flex-col sm:space-x-4 space-y-2 sm:space-y-0 lg:space-y-2 xl:flex-row xl:space-x-2 xl:space-y-0">
{% if user %}
<div class="flex items-center space-x-4">
<span class="head-heavy-2xs">{{ user.get_username }}</span>
<div class="avatar avatar--2xs">
<img
src="{% static "shared/default_avatar.svg" %}"
alt="Tvůj profilový obrázek"
>
</div>
<form action="{% url "oidc_logout" %}" method="POST">
{% csrf_token %}
<button
class="text-grey-200 hover:text-white __tooltipped"
type="submit"
aria-label="Odhlásit se"
><i class="ico--log-out"></i></button>
</form>
</div>
{% else %}
<a
class="btn btn--white btn--hoveractive cursor-pointer"
href="{% url "oidc_authentication_init" %}"
>
<div class="btn__body">Přihlásit se</div>
</a>
{% endif %}
</div>
</div>
</ui-navbar>
</ui-app>
</nav>
</header>
</div>
</ui-navbar>
</ui-app>
</nav>
<main>
{% block content %}{% endblock %}
</main>
<div class="container container--default py-8 lg:py-24">
<main>
{% block content %}{% endblock %}
</main>
</div>
<script
src="https://styleguide.pirati.cz/2.11.x/js/main.bundle.js"
......
import $ from "jquery";
import Vue from "vue/dist/vue.esm.browser.min";
import tippy from "tippy.js";
import "tippy.js/dist/tippy.css";
import "tippy.js/themes/light-border.css";
import "tippy.js/animations/scale-subtle.css";
window["Vue"] = Vue;
$(window).ready(
() => {
// Add tooltips
for (const tooltipElement of $('.__tooltipped')) {
tippy(
tooltipElement,
{
content: tooltipElement.getAttribute("aria-label"),
animation: "scale-subtle"
}
)
}
}
);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment