Merge pull request #873 from nofusscomputing/2025-07-23

This commit is contained in:
Jon
2025-07-23 12:28:24 +09:30
committed by GitHub
65 changed files with 343 additions and 2219 deletions

View File

@ -5,11 +5,17 @@
!!! info
Migration of the old history tables to the new history tables occurs as part of post migration. As such the time it will take to migrate the history is dependent upon how many history entries per model. This should be planned for when upgrading to this version. if for some reason the migration is interrupted, you can safely restart it again by running the migrate command.
!!! note
Permission migration from the old history models to the new Audit History models are not migrated. As such users whom used to be able to access history models will need to be granted the required permission to view the new Audit History models
- Added new model for notes
!!! info
Migration of the old notes tables to the new note tables occurs as part of post migration. As such the time it will take to migrate the history is dependent upon how many history entries per model. This should be planned for when upgrading to this version. if for some reason the migration is interrupted, you can safely restart it again by running the migrate command.
!!! note
Permission migration from the old history models to the new Centurion Notes models are not migrated. As such users whom used to be able to access notes models will need to be granted the required permission to view the new Centurion Notes models
- Removed Django UI
[UI](https://github.com/nofusscomputing/centurion_erp) must be deployed seperatly.

View File

@ -1,4 +1,10 @@
from django.contrib.auth.models import Permission
from django.apps import apps
from django.contrib.auth.models import (
ContentType,
Permission
)
from django.conf import settings
def permission_queryset():
"""Filter Permissions to those used within the application
@ -7,7 +13,7 @@ def permission_queryset():
list: Filtered queryset that only contains the used permissions
"""
apps = [
centurion_apps = [
'access',
'accounting',
'assistance',
@ -52,10 +58,50 @@ def permission_queryset():
'view_history',
]
if not settings.RUNNING_TESTS:
models = apps.get_models()
for model in models:
if(
not str(model._meta.object_name).endswith('AuditHistory')
and not str(model._meta.model_name).lower().endswith('history')
):
# check `endswith('history')` can be removed when the old history models are removed
continue
content_type = ContentType.objects.get(
app_label = model._meta.app_label,
model = model._meta.model_name
)
permissions = Permission.objects.filter(
content_type = content_type,
)
for permission in permissions:
if(
not permission.codename == 'view_' + str(model._meta.model_name)
and str(model._meta.object_name).endswith('AuditHistory')
):
exclude_permissions += [ permission.codename ]
elif(
not str(model._meta.object_name).endswith('AuditHistory')
and str(model._meta.model_name).lower().endswith('history')
):
# This `elif` can be removed when the old history models are removed
exclude_permissions += [ permission.codename ]
return Permission.objects.select_related('content_type').filter(
content_type__app_label__in=apps,
content_type__app_label__in = centurion_apps,
).exclude(
content_type__model__in=exclude_models
content_type__model__in = exclude_models
).exclude(
codename__in = exclude_permissions
)

View File

@ -11,7 +11,7 @@ from access.serializers.role import Role, ModelSerializer
@pytest.mark.model_role
@pytest.mark.module_role
@pytest.mark.model_role
class ValidationSerializer(
TestCase,
):

View File

@ -23,7 +23,7 @@ User = django.contrib.auth.get_user_model()
@pytest.mark.model_role
@pytest.mark.module_role
@pytest.mark.model_role
class ViewSetBase:
add_data: dict = None

View File

@ -43,9 +43,9 @@ class EntityAPITestCases(
'entity_type': {
'expected': str
},
# '_urls.history': {
# 'expected': str
# },
'_urls.history': {
'expected': str
},
'_urls.knowledge_base': {
'expected': str
}

View File

@ -156,7 +156,7 @@ class APITestCases(
@pytest.mark.module_role
@pytest.mark.model_role
class RoleAPITest(
APITestCases,
TestCase,

View File

@ -63,7 +63,7 @@ class RoleModelInheritedCases(
@pytest.mark.module_role
@pytest.mark.model_role
class RoleModelPyTest(
RoleModelTestCases,
):

View File

@ -21,7 +21,7 @@ import pytest
@pytest.mark.model_role
@pytest.mark.module_role
@pytest.mark.model_role
@pytest.mark.skip( reason = 'figure out how to isolate so entirety of unit tests can run without this test failing' )
# @pytest.mark.forked
# @pytest.mark.django_db

View File

@ -47,7 +47,7 @@ class ViewsetTestCases(
@pytest.mark.module_role
@pytest.mark.model_role
class RoleViewsetTest(
ViewsetTestCases,
TestCase,

View File

@ -54,9 +54,9 @@ class APIFieldsTestCases:
'_urls._self': {
'expected': str
},
# '_urls.notes': {
# 'expected': str
# },
'_urls.notes': {
'expected': str
},
}
api_fields_model = {

View File

@ -50,4 +50,37 @@ class SerializerTestCases:
data = kwargs_api_create
)
assert serializer.is_valid(raise_exception = True)
assert serializer.is_valid(raise_exception = True)
@pytest.mark.regression
def test_serializer_create_calls_model_full_clean(self,
kwargs_api_create, mocker, model, model_serializer, request_user
):
""" Serializer Check
Confirm that using valid data the object validates without exceptions.
"""
mock_view = MockView(
user = request_user,
model = model,
action = 'create',
)
serializer = model_serializer['model'](
context = {
'request': mock_view.request,
'view': mock_view,
},
data = kwargs_api_create
)
serializer.is_valid(raise_exception = True)
full_clean = mocker.spy(model, 'full_clean')
serializer.save()
full_clean.assert_called_once()

View File

@ -260,6 +260,101 @@ class ModelTestCases(
@pytest.mark.regression
def test_method_clean_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `clean` is called once only.
"""
if model._meta.abstract:
pytest.xfail( reason = 'model is an Abstract model, test is N/A' )
clean = mocker.spy(model_instance, 'clean')
model_instance.full_clean()
clean.assert_called_once()
@pytest.mark.regression
def test_method_clean_fields_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `clean_fields` is called once only.
"""
if model._meta.abstract:
pytest.xfail( reason = 'model is an Abstract model, test is N/A' )
clean_fields = mocker.spy(model_instance, 'clean_fields')
model_instance.full_clean()
clean_fields.assert_called_once()
@pytest.mark.regression
def test_method_full_clean_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `full_clean` is called once only.
"""
if model._meta.abstract:
pytest.xfail( reason = 'model is an Abstract model, test is N/A' )
full_clean = mocker.spy(model_instance, 'full_clean')
model_instance.save()
full_clean.assert_called_once()
@pytest.mark.regression
def test_method_validate_constraints_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `validate_constraints` is called once only.
"""
if model._meta.abstract:
pytest.xfail( reason = 'model is an Abstract model, test is N/A' )
validate_constraints = mocker.spy(model_instance, 'validate_constraints')
model_instance.full_clean()
validate_constraints.assert_called_once()
@pytest.mark.regression
def test_method_validate_unique_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `validate_unique` is called once only.
"""
if model._meta.abstract:
pytest.xfail( reason = 'model is an Abstract model, test is N/A' )
validate_unique = mocker.spy(model_instance, 'validate_unique')
model_instance.full_clean()
validate_unique.assert_called_once()
@pytest.mark.regression
def test_method_type___str__(self, model, model_instance ):
"""Test Method

View File

@ -0,0 +1,42 @@
# Generated by Django 5.1.10 on 2025-07-23 00:04
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("contenttypes", "0002_remove_content_type_name"),
("core", "0036_alter_ticketbase_external_ref_and_more"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.AlterField(
model_name="centurionmodelnote",
name="content_type",
field=models.ForeignKey(
blank=True,
help_text="Model this note is for",
null=True,
on_delete=django.db.models.deletion.CASCADE,
to="contenttypes.contenttype",
verbose_name="Content Model",
),
),
migrations.AlterField(
model_name="centurionmodelnote",
name="created_by",
field=models.ForeignKey(
blank=True,
help_text="User whom added the Note",
null=True,
on_delete=django.db.models.deletion.PROTECT,
related_name="+",
to=settings.AUTH_USER_MODEL,
verbose_name="Created By",
),
),
]

View File

@ -53,7 +53,7 @@ class CenturionModelNote(
settings.AUTH_USER_MODEL,
blank = True,
help_text = 'User whom added the Note',
null = False,
null = True,
on_delete = models.PROTECT,
related_name = '+',
verbose_name = 'Created By',
@ -75,7 +75,7 @@ class CenturionModelNote(
ContentType,
blank = True,
help_text = 'Model this note is for',
null = False,
null = True,
on_delete=models.CASCADE,
verbose_name = 'Content Model'
)

View File

@ -50,7 +50,7 @@ class CenturionNoteModelTestCases(
'blank': True,
'default': models.fields.NOT_PROVIDED,
'field_type': models.ForeignKey,
'null': False,
'null': True,
'unique': False,
},
'modified_by': {
@ -64,7 +64,7 @@ class CenturionNoteModelTestCases(
'blank': True,
'default': models.fields.NOT_PROVIDED,
'field_type': models.ForeignKey,
'null': False,
'null': True,
'unique': False,
},
'modified': {

View File

@ -173,3 +173,92 @@ class TicketCommentSolutionModelPyTest(
):
sub_model_type = 'solution'
@pytest.mark.regression
def test_method_clean_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `clean` is called once only.
"""
clean = mocker.spy(model_instance, 'clean')
model_instance.ticket.status = model_instance.ticket.__class__.TicketStatus.NEW
model_instance.ticket.is_solved = False
model_instance.save()
clean.assert_called_once()
@pytest.mark.regression
def test_method_clean_fields_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `clean_fields` is called once only.
"""
clean_fields = mocker.spy(model_instance, 'clean_fields')
model_instance.ticket.status = model_instance.ticket.__class__.TicketStatus.NEW
model_instance.ticket.is_solved = False
model_instance.save()
clean_fields.assert_called_once()
@pytest.mark.regression
def test_method_full_clean_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `full_clean` is called once only.
"""
full_clean = mocker.spy(model_instance, 'full_clean')
model_instance.ticket.status = model_instance.ticket.__class__.TicketStatus.NEW
model_instance.ticket.is_solved = False
model_instance.save()
full_clean.assert_called_once()
@pytest.mark.regression
def test_method_validate_constraints_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `validate_constraints` is called once only.
"""
validate_constraints = mocker.spy(model_instance, 'validate_constraints')
model_instance.ticket.status = model_instance.ticket.__class__.TicketStatus.NEW
model_instance.ticket.is_solved = False
model_instance.save()
validate_constraints.assert_called_once()
@pytest.mark.regression
def test_method_validate_unique_called(self, mocker, model, model_instance):
"""Test Method
Ensure method `validate_unique` is called once only.
"""
validate_unique = mocker.spy(model_instance, 'validate_unique')
model_instance.ticket.status = model_instance.ticket.__class__.TicketStatus.NEW
model_instance.ticket.is_solved = False
model_instance.save()
validate_unique.assert_called_once()

View File

@ -95,14 +95,13 @@ CREATE TABLE IF NOT EXISTS "devops_git_group_history" ("modelhistory_ptr_id" int
CREATE TABLE IF NOT EXISTS "devops_github_repository_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "devops_githubrepository" ("gitrepository_ptr_id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "devops_gitlab_repository_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "devops_gitlabrepository" ("gitrepository_ptr_id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "devops_git_group_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "devops_gitgroup" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "access_organization_history" ("modelhistory_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_history" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "access_organization_notes" ("modelnotes_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_notes" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "access_organization_history" ("modelhistory_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_model_history" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "access_company" ("entity_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "access_entity" ("id") DEFERRABLE INITIALLY DEFERRED, "name" varchar(80) NOT NULL);
CREATE TABLE IF NOT EXISTS "access_person" ("entity_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "access_entity" ("id") DEFERRABLE INITIALLY DEFERRED, "f_name" varchar(64) NOT NULL, "l_name" varchar(64) NOT NULL, "dob" date NULL, "m_name" varchar(100) NULL);
CREATE TABLE IF NOT EXISTS "core_ticketcommentaction" ("ticketcommentbase_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_ticketcommentbase" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "core_ticketcommentbase" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "external_ref" integer NULL, "external_system" integer NULL, "comment_type" varchar(30) NOT NULL, "body" text NULL, "private" bool NOT NULL, "duration" integer NOT NULL, "estimation" integer NOT NULL, "is_template" bool NOT NULL, "source" integer NOT NULL, "is_closed" bool NOT NULL, "date_closed" datetime NULL, "created" datetime NOT NULL, "modified" datetime NOT NULL, "category_id" integer NULL REFERENCES "core_ticketcommentcategory" ("id") DEFERRABLE INITIALLY DEFERRED, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "ticket_id" integer NOT NULL REFERENCES "core_ticketbase" ("id") DEFERRABLE INITIALLY DEFERRED, "user_id" integer NULL REFERENCES "access_entity" ("id") DEFERRABLE INITIALLY DEFERRED, "parent_id" integer NULL REFERENCES "core_ticketcommentbase" ("id") DEFERRABLE INITIALLY DEFERRED, "template_id" integer NULL REFERENCES "core_ticketcommentbase" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "core_audithistory" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "before" text NULL CHECK ((JSON_VALID("before") OR "before" IS NULL)), "after" text NULL CHECK ((JSON_VALID("after") OR "after" IS NULL)), "action" integer NULL, "content_type_id" integer NOT NULL REFERENCES "django_content_type" ("id") DEFERRABLE INITIALLY DEFERRED, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "core_centurionmodelnote" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "body" text NOT NULL, "modified" datetime NOT NULL, "content_type_id" integer NOT NULL REFERENCES "django_content_type" ("id") DEFERRABLE INITIALLY DEFERRED, "created_by_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "modified_by_id" integer NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "core_manufacturer" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "name" varchar(50) NOT NULL UNIQUE, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "model_notes" text NULL);
CREATE TABLE IF NOT EXISTS "core_manufacturer_audithistory" ("centurionaudit_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_audithistory" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "core_manufacturer" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "core_manufacturer_centurionmodelnote" ("centurionmodelnote_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_centurionmodelnote" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "core_manufacturer" ("id") DEFERRABLE INITIALLY DEFERRED);
@ -159,6 +158,7 @@ CREATE TABLE IF NOT EXISTS "config_management_configgroupsoftware_audithistory"
CREATE TABLE IF NOT EXISTS "config_management_configgroups" ("model_notes" text NULL, "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "name" varchar(50) NOT NULL, "config" text NULL CHECK ((JSON_VALID("config") OR "config" IS NULL)), "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "parent_id" integer NULL REFERENCES "config_management_configgroups" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "config_management_configgroupsoftware" ("model_notes" text NULL, "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "modified" datetime NOT NULL, "action" integer NULL, "config_group_id" integer NOT NULL REFERENCES "config_management_configgroups" ("id") DEFERRABLE INITIALLY DEFERRED, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "software_id" integer NOT NULL REFERENCES "itam_software" ("id") DEFERRABLE INITIALLY DEFERRED, "version_id" integer NULL REFERENCES "itam_softwareversion" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "core_ticketbase" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "external_ref" integer NULL, "ticket_type" varchar(30) NOT NULL, "status" integer NOT NULL, "title" varchar(150) NOT NULL UNIQUE, "description" text NULL, "private" bool NOT NULL, "urgency" integer NULL, "impact" integer NULL, "priority" integer NULL, "planned_start_date" datetime NULL, "planned_finish_date" datetime NULL, "real_start_date" datetime NULL, "real_finish_date" datetime NULL, "is_deleted" bool NOT NULL, "is_solved" bool NOT NULL, "date_solved" datetime NULL, "is_closed" bool NOT NULL, "date_closed" datetime NULL, "created" datetime NOT NULL, "modified" datetime NOT NULL, "category_id" integer NULL REFERENCES "core_ticketcategory" ("id") DEFERRABLE INITIALLY DEFERRED, "milestone_id" integer NULL REFERENCES "project_management_projectmilestone" ("id") DEFERRABLE INITIALLY DEFERRED, "opened_by_id" integer NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "project_id" integer NULL REFERENCES "project_management_project" ("id") DEFERRABLE INITIALLY DEFERRED, "external_system" integer NULL, "parent_ticket_id" integer NULL REFERENCES "core_ticketbase" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "core_centurionmodelnote" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "body" text NOT NULL, "modified" datetime NOT NULL, "content_type_id" integer NULL REFERENCES "django_content_type" ("id") DEFERRABLE INITIALLY DEFERRED, "modified_by_id" integer NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "created_by_id" integer NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "devops_gitgroup_audithistory" ("centurionaudit_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_audithistory" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "devops_gitgroup" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "devops_gitgroup" ("model_notes" text NULL, "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "provider" integer NOT NULL, "provider_pk" integer NULL, "name" varchar(80) NOT NULL, "path" varchar(80) NOT NULL, "description" text NULL, "created" datetime NOT NULL, "organization_id" integer NOT NULL REFERENCES "access_tenant" ("id") DEFERRABLE INITIALLY DEFERRED, "modified" datetime NOT NULL, "parent_group_id" integer NULL REFERENCES "devops_gitgroup" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE TABLE IF NOT EXISTS "devops_gitgroup_centurionmodelnote" ("centurionmodelnote_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "core_centurionmodelnote" ("id") DEFERRABLE INITIALLY DEFERRED, "model_id" integer NOT NULL REFERENCES "devops_gitgroup" ("id") DEFERRABLE INITIALLY DEFERRED);
@ -239,7 +239,7 @@ CREATE TABLE IF NOT EXISTS "social_auth_nonce" ("id" integer NOT NULL PRIMARY KE
CREATE TABLE IF NOT EXISTS "social_auth_usersocialauth" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "provider" varchar(32) NOT NULL, "uid" varchar(255) NOT NULL, "user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE INITIALLY DEFERRED, "created" datetime NOT NULL, "modified" datetime NOT NULL, "extra_data" text NOT NULL CHECK ((JSON_VALID("extra_data") OR "extra_data" IS NULL)));
CREATE TABLE IF NOT EXISTS "social_auth_partial" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "token" varchar(32) NOT NULL, "next_step" smallint unsigned NOT NULL CHECK ("next_step" >= 0), "backend" varchar(32) NOT NULL, "timestamp" datetime NOT NULL, "data" text NOT NULL CHECK ((JSON_VALID("data") OR "data" IS NULL)));
DELETE FROM sqlite_sequence;
INSERT INTO sqlite_sequence VALUES('django_migrations',231);
INSERT INTO sqlite_sequence VALUES('django_migrations',232);
INSERT INTO sqlite_sequence VALUES('django_content_type',218);
INSERT INTO sqlite_sequence VALUES('auth_permission',917);
INSERT INTO sqlite_sequence VALUES('auth_group',0);
@ -271,6 +271,7 @@ INSERT INTO sqlite_sequence VALUES('config_management_configgrouphosts',0);
INSERT INTO sqlite_sequence VALUES('config_management_configgroups',0);
INSERT INTO sqlite_sequence VALUES('config_management_configgroupsoftware',0);
INSERT INTO sqlite_sequence VALUES('core_ticketbase',0);
INSERT INTO sqlite_sequence VALUES('core_centurionmodelnote',0);
INSERT INTO sqlite_sequence VALUES('devops_gitgroup',0);
INSERT INTO sqlite_sequence VALUES('devops_featureflag',0);
INSERT INTO sqlite_sequence VALUES('devops_gitrepository',0);

View File

@ -7,385 +7,3 @@ body {
margin: 0px;
background: #f0f0f0;
}
h1#site-title {
width: 275px;
height: 76px;
line-height: 76px;
vertical-align: middle;
padding: 0%;
margin: 0%;
}
h2#content_title {
width: 100%;
background-color: #fff;
height: 80px;
line-height: 80px;
text-align: center;
vertical-align: middle;
margin: 0px;
vertical-align: middle;
align-content: center;
padding-right: 50px;
padding-left: 50px
}
.codehilite {
display: inline;
}
span#content_header_icon {
float: right;
width: 30px;
height: 100%;
margin-right: 10px;
text-align: center;
align-content: center;
color: #177ee6;
}
span.icon-text {
vertical-align: middle;
border-radius: 25px;
font-size: inherit;
border: 1px solid #ccc;
line-height: 30px;
padding-left: 1px;
padding-right: 10px;
height: 30px;
display: inline-block;
margin-left: 5px;
}
span.icon-text a {
text-decoration: unset;
color: inherit;
}
span.icon-text a:visited {
text-decoration: unset;
color: inherit;
}
span.add {
color: #315f9c;
}
span.icon-add {
fill: #315f9c;
height: 30px;
line-height: 30px;
margin: 0px;
margin-bottom: -7px;
padding: 0px;
vertical-align: middle;
display: inline-block;
}
span.success {
color: #319c3a;
}
span.icon-success {
fill: #319c3a;
height: 30px;
line-height: 30px;
margin: 0px;
margin-bottom: -7px;
padding: 0px;
vertical-align: middle;
display: inline-block;
}
span.cross {
color: #9c3131;
}
span.icon-cross {
fill: #9c3131;
height: 30px;
line-height: 30px;
margin: 0px;
margin-bottom: -7px;
padding: 0px;
vertical-align: middle;
display: inline-block;
}
span.change {
color: #cab706;
}
span.icon-change {
fill: #cab706;
height: 30px;
line-height: 30px;
margin: 0px;
margin-bottom: -7px;
padding: 0px;
vertical-align: middle;
display: inline-block;
}
span.issue {
color: #fc6d26;
}
span.icon-issue {
fill: #fc6d26;
height: 30px;
line-height: 30px;
margin: 0px;
/* margin-bottom: -2px; */
padding: 0px;
vertical-align: middle;
display: inline-block;
}
span.icon-external-link {
height: 30px;
line-height: 30px;
margin: 0px;
padding: 0px;
vertical-align: middle;
display: inline-block;
width: 25px;
}
/* .icon {
display: block;
content: none;
background-color: #3e8e41;
} */
header {
display: flex;
flex-direction: row;
position: fixed;
top: 0px;
width: 100%;
background-color: #151515;
text-align: center;
color: white;
height: 76px;
/* line-height: 76px; */
vertical-align: middle;
}
section {
display: flexbox;
width: 100%;
padding-top: 76px;
padding-left: 275px;
}
article {
background-color: #fff;
padding: 10px;
margin: 20px;
border: 1px solid #e6dcdc;
}
footer {
background-color: #fff;
width: 100%;
height: 76px;
line-height: 76px;
text-align: center;
vertical-align: middle;
padding: 0%;
margin: 0%;
color: #aaa;
font-size: 12px;
}
footer span {
display: inline-block;
width: 33%;
padding: 0px 10px 0px 10px;
margin: 0px;
vertical-align: middle;
height: 100%;
/*line-height: 76px;*/
}
footer span svg {
height: 100%;
width: 30px;
fill: #177ee6
}
/* Style The Dropdown Button */
.dropbtn {
background-color: #177ee6;
color: white;
padding: 10px;
font-size: 16px;
border: none;
cursor: pointer;
min-width: 160px;
}
.accbtn {
background-color: inherit;
color: #000;
padding: 10px;
font-size: 16px;
border: none;
cursor: pointer;
width: 100%;
margin: 0px;
}
header .dropdown {
padding-top: 19px;
}
/* The container <div> - needed to position the dropdown content */
.dropdown {
/* position: fixed; */
/* display: inline-block; */
display: inline-flexbox;
/* left: 300px; */
/* position: relative; */
/* vertical-align: middle; */
}
/* Dropdown Content (Hidden by Default) */
.dropdown-content {
display: none;
position: absolute;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.dropdown-content form {
margin: 0px;
padding: 0px;
}
.accbtn:hover {
background-color: #b4adad
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown-content a:hover {
background-color: #b4adad
}
.dropdown:hover .dropdown-content {
display: block;
}
.dropdown:hover .dropbtn {
background-color: #177ee6;
}
nav {
display: flex;
flex-direction: column;
background: #212427;
padding: 20px;
width: 275px;
height: 100%;
position: fixed;
top: 76px;
bottom: 4rem;
left: 0;
overflow-y: auto;
}
nav button.collapsible {
background-color: inherit;
color: white;
cursor: pointer;
padding: 0px 18px 0px 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
margin: 0px;
line-height: 50px;
vertical-align: middle;
}
nav button.active, .collapsible:hover {
font-weight: bold;
}
nav button.collapsible:after {
content: url('/static/icons/nav_arrow_right.svg');
color: white;
float: right;
margin-left: 5px;
}
nav button.active:after {
content: url('/static/icons/nav_arrow_down.svg');
font-weight: bold;
}
nav div.content {
padding: 0px;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
margin: 0px;
}
nav ul {
list-style-type: none;
padding: 0;
margin: 0px;
}
nav ul li {
padding: 10px;
}
nav ul li:hover {
border-left: 3px solid #73bcf7;
background-color: #666;
}
nav ul li.active {
border-left: 3px solid #73bcf7;
}
nav a {
color: #177ee6;
text-decoration: none;
}
nav a:visited {
color: #177ee6;
text-decoration: none;
}

View File

@ -1,75 +0,0 @@
pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.codehilite .hll { background-color: #ffffcc }
.codehilite { background: #f8f8f8; padding: 5px; border: 1px solid #ccc; font-size: 11pt;}
.codehilite .c { color: #3D7B7B; font-style: italic } /* Comment */
.codehilite .err { border: 1px solid #FF0000 } /* Error */
.codehilite .k { color: #008000; font-weight: bold } /* Keyword */
.codehilite .o { color: #666666 } /* Operator */
.codehilite .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.codehilite .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.codehilite .cp { color: #9C6500 } /* Comment.Preproc */
.codehilite .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.codehilite .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.codehilite .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.codehilite .gd { color: #A00000 } /* Generic.Deleted */
.codehilite .ge { font-style: italic } /* Generic.Emph */
.codehilite .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.codehilite .gr { color: #E40000 } /* Generic.Error */
.codehilite .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.codehilite .gi { color: #008400 } /* Generic.Inserted */
.codehilite .go { color: #717171 } /* Generic.Output */
.codehilite .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.codehilite .gs { font-weight: bold } /* Generic.Strong */
.codehilite .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.codehilite .gt { color: #0044DD } /* Generic.Traceback */
.codehilite .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.codehilite .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.codehilite .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.codehilite .kp { color: #008000 } /* Keyword.Pseudo */
.codehilite .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.codehilite .kt { color: #B00040 } /* Keyword.Type */
.codehilite .m { color: #666666 } /* Literal.Number */
.codehilite .s { color: #BA2121 } /* Literal.String */
.codehilite .na { color: #687822 } /* Name.Attribute */
.codehilite .nb { color: #008000 } /* Name.Builtin */
.codehilite .nc { color: #0000FF; font-weight: bold } /* Name.Class */
.codehilite .no { color: #880000 } /* Name.Constant */
.codehilite .nd { color: #AA22FF } /* Name.Decorator */
.codehilite .ni { color: #717171; font-weight: bold } /* Name.Entity */
.codehilite .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.codehilite .nf { color: #0000FF } /* Name.Function */
.codehilite .nl { color: #767600 } /* Name.Label */
.codehilite .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
.codehilite .nt { color: #008000; font-weight: bold } /* Name.Tag */
.codehilite .nv { color: #19177C } /* Name.Variable */
.codehilite .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
.codehilite .w { color: #bbbbbb } /* Text.Whitespace */
.codehilite .mb { color: #666666 } /* Literal.Number.Bin */
.codehilite .mf { color: #666666 } /* Literal.Number.Float */
.codehilite .mh { color: #666666 } /* Literal.Number.Hex */
.codehilite .mi { color: #666666 } /* Literal.Number.Integer */
.codehilite .mo { color: #666666 } /* Literal.Number.Oct */
.codehilite .sa { color: #BA2121 } /* Literal.String.Affix */
.codehilite .sb { color: #BA2121 } /* Literal.String.Backtick */
.codehilite .sc { color: #BA2121 } /* Literal.String.Char */
.codehilite .dl { color: #BA2121 } /* Literal.String.Delimiter */
.codehilite .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.codehilite .s2 { color: #BA2121 } /* Literal.String.Double */
.codehilite .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.codehilite .sh { color: #BA2121 } /* Literal.String.Heredoc */
.codehilite .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.codehilite .sx { color: #008000 } /* Literal.String.Other */
.codehilite .sr { color: #A45A77 } /* Literal.String.Regex */
.codehilite .s1 { color: #BA2121 } /* Literal.String.Single */
.codehilite .ss { color: #19177C } /* Literal.String.Symbol */
.codehilite .bp { color: #008000 } /* Name.Builtin.Pseudo */
.codehilite .fm { color: #0000FF } /* Name.Function.Magic */
.codehilite .vc { color: #19177C } /* Name.Variable.Class */
.codehilite .vg { color: #19177C } /* Name.Variable.Global */
.codehilite .vi { color: #19177C } /* Name.Variable.Instance */
.codehilite .vm { color: #19177C } /* Name.Variable.Magic */
.codehilite .il { color: #666666 } /* Literal.Number.Integer.Long */

View File

@ -1,318 +0,0 @@
/*******************************************************************************
refactored
*******************************************************************************/
#content-body form div label {
display: inline-block;
line-height: inherit;
text-align: right;
width: 200px;
}
#content-body form div .helptext {
color: #999;
display: inline;
font-size: 12px;
}
#content-body form div input[type=text],
#content-body form div select {
background-color: #fff;
border: none;
border-bottom: 1px solid #ccc;
font-size: inherit;
height: 30px;
line-height: inherit;
width: 400px;
}
#content-body form#dynamic-form {
align-content: center;
align-items: center;
justify-content: center;
line-height: 30px;
padding: 10px;
/* text-align: center; */
text-align: right;
width: 650px;
}
#content-body form#dynamic-form div:not(#markdown) {
align-items: center;
display: block;
line-height: inherit;
justify-content: center;
padding: 5px;
text-align: center;
width: 100%;
}
input[type=button],
input[type=submit] {
background-color: #177ee6;
border: none;
border-radius: 5px;
color: #fff;
cursor: pointer;
height: 30px;
margin: 10px;
}
/* Style the navigation tabs at the top of a content page */
.content-navigation-tabs {
display: block;
overflow: hidden;
border-bottom: 1px solid #ccc;
/* background-color: #f1f1f1; */
width: 100%;
text-align: left;
padding: 0px;
margin: 0px
}
.content-navigation-tabs-link {
border: 0px;
margin: none;
padding: none;
}
/* Style the buttons that are used to open the tab content */
.content-navigation-tabs button {
display: inline;
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
margin: 0px;
padding: 0px;
padding: 14px 16px;
transition: 0.3s;
font-size: inherit;
color: #6a6e73;
}
/* Change background color of buttons on hover */
.content-navigation-tabs button:hover {
/* background-color: #ddd; */
border-bottom: 3px solid #ccc;
}
/* Create an active/current tablink class */
.content-navigation-tabs button.active {
/* background-color: #ccc; */
border-bottom: 3px solid #177ee6;
}
/* Style content for each tab */
.content-tab {
width: 100%;
display: none;
padding-bottom: 0px;
border: none;
border-top: none;
}
.content-tab hr {
border: none;
border-top: 1px solid #ccc;
}
.content-tab pre {
word-wrap: break-word;
white-space: pre-wrap;
}
/* Style for section fields on details page */
.detail-view-field {
display: unset;
height: 30px;
line-height: 30px;
padding: 0px 20px 40px 20px;
}
.detail-view-field label {
display: inline-block;
font-weight: bold;
width: 200px;
margin: 10px;
height: 30px;
line-height: 30px;
}
.detail-view-field span {
display: inline-block;
width: 340px;
margin: 10px;
border-bottom: 1px solid #ccc;
height: 30px;
line-height: 30px;
}
/*******************************************************************************
EoF refactored
*******************************************************************************/
main section a {
color: #177ee6;
text-decoration: none;
}
main section a:visited {
color: #177ee6;
text-decoration: none;
}
article div:not(.codehilite) {
/* background-color: #ff0000; */
justify-content: center;
width: 100%;
/* display: block; */
display: flex;
flex-wrap: wrap;
}
table {
width: 100%;
text-align: center;
}
tr {
height: 30px;
}
td {
border-bottom: 1px solid #ccc;
padding: 20px;
}
section .content-header {
display: flex;
/* background-color: #08f008; */
align-items: center;
width: 100%;
justify-content: space-evenly;
padding: 0px;
min-height: 120px;
}
section .content-header fieldset {
/* background-color: #0851f0; */
width: 350px;
padding: 0px;
border: none;
}
section .content-header fieldset label {
display: block;
width: 100%;
height: 30px;
line-height: 30px;
}
section .content-header fieldset input {
display: block;
width: 100%;
height: 30px;
line-height: 30px;
}
.comments {
background-color: #f0f0f0;
padding: 10px;
margin: 10px -20px -50px -20px;
width: auto;
}
.comment {
background-color: #fff;
margin: 10px 5px 10px 5px;
padding: 5px;
border-radius: 10px;
border: 1px solid #e6dcdc;
}
.comment-header {
text-align: left;
font-size: 12px;
color: #999;
margin: 0px;
padding: 2px;
height: 30px;
}
.comment-header svg {
fill: #999;
height: 100%;
margin: auto 0 auto 0;
}
.comment-header span {
line-height: auto;
margin: auto;
margin: auto 10px auto 2px;
}
.comment-body {
display:inline-block;
padding: 10px 5px 10px 20px;
}
.comment-footer {
color: #999;
font-size: 12px;
padding: 2px;
width: 100%;
}
.comment-footer svg {
fill: #999;
height: 100%;
margin: auto 0 auto 0;
}
.comment-footer span {
line-height: auto;
margin: auto 10px auto 2px;
}

View File

@ -1,16 +0,0 @@
function openContentNavigationTab(evt, TabName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("content-tab");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("content-navigation-tabs-link");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(TabName).style.display = "block";
evt.currentTarget.className += " active";
}

View File

@ -1,787 +0,0 @@
#badge {
display: table;
padding: 1px 5px 0px 2px;
margin: 0px;
border: 1px solid #ccc;
border-radius: 15px;
/* height:fit-content; */
}
#badge #text {
display: inline-block;
vertical-align: middle;
margin: 0px;
padding: 0px;
padding-left: 5px;
}
#badge #icon {
display: inline-block;
width: 20px;
vertical-align: middle;
padding: 0px;
margin: 0px;
}
#badge .icon svg{
width: 20px;
height: 20px;
}
#linked-tickets {
display: table;
padding: 0px;
margin: 0px;
}
#linked-tickets .ticket {
display: inline-block;
line-height: 30px;
vertical-align: middle;
margin: 0px;
padding: 0px;
}
#linked-tickets .ticket svg{
display: inline;
width: 20px;
height: 30px;
}
#linked-tickets .icon {
display: inline-block;
width: 20px;
line-height: 30px;
vertical-align: middle;
padding: 0px;
margin: 0px;
}
#linked-tickets .icon svg{
display: inline;
width: 20px;
height: 30px;
}
#linked-tickets .icon.icon-related svg{
background-color: #afdbff;
border-radius: 10px;
fill: #0b91ff;
height: 20px;
}
#linked-tickets .icon.icon-blocks svg{
background-color: #fcd5b1;
border-radius: 10px;
fill: #e79b37;
height: 20px;
}
#linked-tickets .icon.icon-blocked_by svg{
background-color: #f3c6c6;
border-radius: 10px;
fill: #ff1c1c;
height: 20px;
}
#linked-tickets .ticket #ticket-icon {
display: inline-block;
width: 20px;
line-height: 30px;
vertical-align: middle;
padding: 0px;
margin: 0px 5px 0px 0px;
height: 20px;
}
#linked-tickets .ticket #ticket-icon svg {
display: inline;
height: 22px;
padding: 1px;
border: none;
border-radius: 10px;
}
#ticket-additional-data {
padding-right: 10px;
}
#ticket-additional-data div {
margin-top: 10px;
padding: 0px;
}
#ticket-content {
display: flex;
height: auto;
margin: 20px;
padding: 0px;
width: auto;
font-size: 12pt;
}
#ticket-content div {
display: inline-block;
}
#ticket-data {
margin: 0px;
padding: 0px;
width: 100%;
}
#ticket-data div {
display: block;
}
#ticket-description {
background-color: #fff;
border: 1px solid #ccc;
margin: 0px 10px 0px 0px;
padding: 0px;
}
#ticket-description h3 {
font-size: inherit;
font-weight: normal;
height: 30px;
line-height: 30px;
margin: 0px;
padding: 0px 10px 0px 10px;
text-align: left;
}
#ticket-description h3 span.sub-script {
color: #777;
font-size:smaller;
}
#ticket-description div {
padding: 10px;
}
#data-block {
border: 1px solid #ccc;
padding: 0px;
}
#data-block h3 button {
float: right;
height: 20px;
margin-bottom: auto;
margin-top: auto;
}
#data-block div {
margin: 0px;
padding: 0px;
padding-left: 10px;
}
#data-block.linked-item div#item {
display: inline-block;
text-align: center;
width: 33%;
}
#data-block.linked-item div#item p{
margin: 0px;
padding: 0px;
}
#ticket-comments {
padding: 10px;
}
#ticket-comments ul {
padding: 0px;
padding-left: 30px;
margin: 0px;
}
#ticket-comments li:not(#Action) {
line-height: 30px;
margin: 0px;
margin-bottom: 30px;
padding-left: 10px;
}
#ticket-comments li#Action {
line-height: 30px;
margin: 0px;
margin-bottom: -10px;
margin-top: -20px;
padding-left: 10px;
}
#data-block h3 {
background-color: #177ee6;
color: #fff;
display: flex;
font-size: 16px;
height: 30px;
line-height: 30px;
margin: 0px;
padding-left: 5px;
}
#data-block h3 #text {
height: inherit;
line-height: inherit;
padding: 0px;
width: 100%;
}
#data-block h3 #icons {
height: inherit;
line-height: inherit;
margin-right: 0px;
margin-left: auto;
text-align: right;
width: 200px;
}
#data-block h3 #icons svg {
height: 30px;
margin: 0px;
margin-right: 5px;
width: 20px;
fill: #fff;
}
#rendered-ticket-link {
display: flexbox;
line-height: 30px;
}
#rendered-ticket-link #text{
display: inline-block;
height: 20px;
line-height: inherit;
font-size: inherit;
}
#icon.ticket-status {
display: inline-block;
width: 20px;
height: 20px;
line-height: 30px;
margin: 0px;
vertical-align: middle;
}
#rendered-ticket-link #icon.ticket-status svg {
width: 20px;
height: 20px;
margin: 0px;
line-height: inherit;
}
#icon.ticket-status-assigned svg {
background-color: #e1ffb2;
border: none;
border-radius: 10px;
fill: #2e9200;
}
#icon.ticket-status-assigned_planning svg {
background-color: #e1ffb2;
border: none;
border-radius: 10px;
fill: #2e9200;
}
#icon.ticket-status-approvals svg {
background-color: #ffceb2;
border: none;
border-radius: 10px;
fill: #d86100;
}
#icon.ticket-status-accepted svg {
background-color: #e1ffb2;
border: none;
border-radius: 10px;
fill: #2e9200;
}
#icon.ticket-status-evaluation svg {
background-color: #b2d6ff;
border: none;
border-radius: 10px;
fill: #007592;
}
#icon.ticket-status-testing svg {
background-color: #b2d3ff;
border: none;
border-radius: 10px;
fill: #8c00ff;
}
#icon.ticket-status-draft svg {
background-color: #cacaca;
border: none;
border-radius: 10px;
fill: #4d4d4d;
}
#icon.ticket-status-new svg {
background-color: #b2dcff;
border: none;
border-radius: 10px;
fill: #004492;
}
#icon.ticket-status-pending svg {
background-color: #ffceb2;
border: none;
border-radius: 10px;
fill: #d86100;
}
#icon.ticket-status-solved svg {
background-color: #c9b2ff;
border: none;
border-radius: 10px;
fill: #640092;
}
#icon.ticket-status-closed svg {
background-color: #c9b2ff;
border: none;
border-radius: 10px;
fill: #640092;
}
#icon.ticket-status-invalid svg {
background-color: #ffb2b6;
border: none;
border-radius: 10px;
fill: #920000;
}
#ticket-comments #comment {
border: 1px solid #177ee6;
}
#ticket-comments #comment h4 {
background-color: #177ee6;
border: none;
color: #fff;
display: flex;
font-size: inherit;
height: 30px;
line-height: 30px;
margin: 0px;
padding-left: 5px;
}
#comment h4 #text {
height: inherit;
line-height: inherit;
padding: 0px;
text-align: left;
width: 100%;
}
#comment h4 #text span.sub-script{
font-size: smaller;
}
#comment h4 #icons {
border: none;
display: inline-block;
height: inherit;
line-height: inherit;
margin-right: 0px;
margin-left: auto;
text-align: right;
width: 200px;
}
#ticket-comments #comment h4 #icons svg {
fill: #fff;
height: 30px;
margin: 0px;
margin-right: 5px;
width: 20px;
}
#discussion {
margin: 0px;
}
#discussion h4 {
border-left: 1px solid #177fe66e;
border-right: 1px solid #177fe66e;
display: block;
margin: 0px;
margin-right: 0px;
margin-left: auto;
height: 30px;
line-height: inherit;
text-align: right;
padding: 0px;
}
#discussion svg {
width: 20px;
height: 30px;
margin: 0px;
margin-right: 5px;
margin-left: 5px;
}
#ticket-meta {
background-color: #fff;
width: 400px;
border: 1px solid #ccc;
margin-right: 0px;
margin-left: auto;
padding: 0px;
}
#ticket-meta h3 {
line-height: 30px;
height: 30px;
margin: 0px;
text-align: center;
}
#ticket-meta fieldset {
display: block;
margin: 10px;
border: none;
}
#ticket-meta fieldset label {
width: 100%;
display: block;
line-height: 30px;
font-weight: bold;
}
#ticket-meta fieldset span.text {
/*width: 100%;*/
display: block;
line-height: 30px;
border: none;
border-bottom: 1px solid #ccc;
}
.incident-ticket {
background-color: #f7baba;
}
.request-ticket {
background-color: #f7e9ba;
}
.change-ticket {
background-color: #badff7;
}
.problem-ticket {
background-color: #f7d0ba;
}
.issue-ticket {
background-color: #baf7db;
}
.project_task-ticket {
background-color: #c5baf7;
}
.comment-type-default {
background-color: #fff;
}
.comment-type-Notification {
background-color: #96c7ff;
}
.comment-type-Solution {
background-color: #b7ff96;
}
.comment-type-Task {
background-color: #f8ff96;
}
#comment fieldset {
border: none;
display: inline-block;
line-height: 14pt;
width: 200px;
font-size: 10pt;
}
#comment fieldset label {
display: block;
font-weight: bold;
line-height: inherit;
}
#comment fieldset span {
display: block;
line-height: inherit;
}
#comment hr {
border: none;
border-bottom: 1px solid #ccc;
margin: 0px 5px 0px 5px;
}
#markdown {
font-size: 12pt;
}
#markdown p {
font-size: inherit;
}
div#markdown {
justify-content: center;
display: block;
text-align: left;
padding: 10px;
}
#markdown .codehilite {
display: block;
width: 100%;
word-wrap: break-word;
white-space: pre-wrap;
}
#markdown h1 {
background-color: inherit;
color: inherit;
font-size: 24px;
line-height: 24px;
padding: 24px 0px 48px 0px;
margin: 0px;
text-align: left;
}
#markdown h2 {
background-color: inherit;
color: inherit;
font-size: 20px;
line-height: 20px;
padding: 20px 0px 40px 0px;
margin: 0px;
text-align: left;
}
#markdown h3 {
background-color: inherit;
color: inherit;
font-size: 18px;
line-height: 18px;
padding: 18px 0px 36px 0px;
margin: 0px;
text-align: left;
}
#markdown h4 {
background-color: inherit;
color: #000;
font-size: 16px;
line-height: 16px;
padding: 16px 0px 32px 0px;
margin: 0px;
text-align: left;
}
#markdown h5 {
background-color: inherit;
color: #000;
font-size: 14px;
line-height: 14px;
padding: 14px 0px 28px 0px;;
margin: 0px;
text-align: left;
}
#markdown li {
background-color: inherit;
font-size: inherit;
line-height: 25px;
padding: 5px;
margin: 0px;
text-align: left;
}
#markdown p:not(div.admonition p){
background-color: inherit;
font-size: inherit;
line-height: 25px;
padding: 0px;
margin: 0px;
text-align: left;
}
#markdown div.admonition {
border-width: 1px;
border-style: solid;
border-radius: 10px;
font-size: inherit;
margin: 10px;
padding: 0px;
}
#markdown div.admonition p.admonition-title {
border-top-left-radius: 10px;
border-top-right-radius: 10px;
font-size: inherit;
margin: 0px;
padding: 2px 10px 2px 10px;
width: 100%;
}
#markdown div.admonition p:not(p.admonition-title) {
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
font-size: inherit;
padding: 10px;
margin: 0px;
width: 100%;
}
#markdown div.admonition.info {
background-color: #b6f5dd;
border-color:#27ffbe;
}
#markdown div.admonition.info p.admonition-title {
background-color: #1ef59170;
}
#markdown div.admonition.note {
background-color: #b6d3f5;
border-color:#278cff;
}
#markdown div.admonition.note p.admonition-title {
background-color: #1e82f570;
color: #fff;
}
#markdown div.admonition.tip {
background-color: #bbf5b6;
border-color:#39ff27;
}
#markdown div.admonition.tip p.admonition-title {
background-color: #37f51e70;
color: #fff;
}
#markdown div.admonition.warning {
background-color: #f5d8b6;
border-color:#ffa127;
}
#markdown div.admonition.warning p.admonition-title {
background-color: #f5911e70;
color: #fff;
}
#markdown div.admonition.danger {
background-color: #f5b6b6;
border-color:#ff2727;
}
#markdown div.admonition.danger p.admonition-title {
background-color: #f51e1e70;
color: #fff;
}
#markdown div.admonition.quote {
background-color: #d3d3d3;
border-color:#868686;
}
#markdown div.admonition.quote p.admonition-title {
background-color: #81818170;
color: #fff;
}
#markdown div.admonition.quote p:not(p.admonition-title) {
font-style: italic;
}

View File

@ -12,143 +12,15 @@
<meta http-equiv="refresh" content="0; url=/{{ settings.LOGIN_URL }}" />
{% else %}
<link rel="stylesheet" href="{% static 'base.css' %}">
<link rel="stylesheet" href="{% static 'code.css' %}">
<link rel="stylesheet" href="{% static 'content.css' %}">
{% block additional-stylesheet %}{% endblock additional-stylesheet %}
<script src="{% static 'functions.js' %}"></script>
{% endif %}
</head>
<body>
{% block body %}
<header>
<h1 id="site-title"><a href="/" style="text-decoration: none; color: inherit;">{% settings_value "SITE_TITLE" %}</a></h1>
{%if user.is_authenticated %}
<div class="dropdown" style="right: 0px; position: fixed; padding-right: 50px;">
<button class="dropbtn">{% block user_name %}{%if user.username %}{{ user.username }}{% else %}My Account{% endif %}{% endblock %}</button>
<div class="dropdown-content">
<!-- <a href="#">Link 1</a> -->
{% if user.is_superuser or user.is_staff %}
<form action="{% url 'admin:index' %}" method="post">
{% csrf_token %}
<button class="accbtn">Admin Panel</button>
</form>
{% endif %}
<form action="{% url '_settings_user' pk=user_settings %}" method="post">
{% csrf_token %}
<button class="accbtn">Settings</button>
</form>
<form action="{% url 'password_change' %}" method="post">
{% csrf_token %}
<button class="accbtn">Change Password</button>
</form>
<form action="{% url 'logout' %}" method="post">
{% csrf_token %}
<button class="accbtn">Log Out</button>
</form>
</div>
</div>
{% endif %}
</header>
<main>
<nav style="padding: 0px;">
{% include 'navigation.html.j2' %}
</nav>
<style>
section h2 span svg {
height: 100%;
margin: auto 0 auto 0;
fill: #666;
cursor: pointer;
width: 30px;
/*height: 30px;*/
}
.icon-delete svg {
fill: #ff0000;
}
.icon-help svg {
fill: #177ee6;
}
.warning-bar {
background-color: #f1d599;
border: 1px solid #ecb785;
height: 30px;
line-height: 30px;
width: 100%;
padding: 0px 20px 0px 20px
}
</style>
<section>
<h2 id="content_title">{% block title %}{{ content_title }}{% endblock %}
{% if model_delete_url %}
<span title="Delete Item" id="content_header_icon" class="icon-delete" onclick="window.location='{{ model_delete_url }}';">
{% include 'icons/delete.svg' %}
</span>
{% endif %}
{% if model_docs_path %}
<span title="Help" id="content_header_icon" class="icon-help" onclick="window.open('{% settings_value 'DOCS_ROOT' %}{{ model_docs_path }}', '_blank')">
{% include 'icons/help.svg' %}
</span>
{% endif %}
</h2>
{% if user.is_authenticated %}
{% if not user_default_organization %}
<div class="warning-bar">You do not have a <b>default organization</b> set, go to <a href="{% url '_settings_user' pk=user_settings %}">user settings</a> to set one</div>
{% endif %}
{% endif %}
{% block article %}
<article id="content-body">
{% block content %}{% endblock %}
</article>
{% endblock article %}
<style>
</style>
<footer>
<span style=" text-align: left;">
<a title="Documentation" href="https://nofusscomputing.com/projects/centurion_erp/" target="_blank">
{% include 'icons/documentation.svg' %}
</a>
<a title="Rest API" href="/api/" target="_blank">
{% include 'icons/api.svg' %}
</a>
<a title="Swagger API Documentation" href="/api/v2/docs" target="_blank">
{% include 'icons/swagger_docs.svg' %}
</a>
<a title="Code Home" href="{{ build_details.project_url }}" target="_blank">
{% include 'icons/git.svg' %}
</a>
</span>
<span style="text-align: center;">
Centurion ERP brought to you by <a href="https://nofusscomputing.com" target="_blank">No Fuss Computing</a>
</span>
<span style="text-align: right;">
Release:
{% if build_details.version %}
version: {{ build_details.version }}
{% else %}
development
{% endif %}
( {% if build_details.project_url %}<a href="{{ build_details.project_url }}/commit/{{ build_details.sha }}" target="_blank">{% endif %}
{{ build_details.sha }}
{% if build_details.project_url %}</a>{% endif %} )
</span>
</footer>
</section>
</main>
{% endblock body %}
{% block body %}{% endblock body %}
</body>

View File

@ -1,101 +0,0 @@
{% load json %}
{% load markdown %}
{% load choice_ids %}
{% block additional-stylesheet %}
{% load static %}
<link rel="stylesheet" href="{% static 'ticketing.css' %}">
{% endblock additional-stylesheet %}
{% if field.widget_type == 'textarea' or field.label == 'Notes' %}
{% if field.name in section.json and field.value %}
<pre style="width: 80%; text-align: left; display:inline; border: 1px solid #ccc; padding: 22px;">{{ field.value.strip | json_pretty | safe }}</pre>
{% elif field.name in section.markdown or field.label == 'Notes' %}
{% if field.label == 'Notes' %}
<div>
<label style="font-weight: bold; width: 100%; border-bottom: 1px solid #ccc; display: block; text-align: inherit;">
{{ field.label }}
</label>
<div id="markdown" style="display: inline-block; text-align: left;">
{% if field.value %}
{{ field.value | markdown | safe }}
{% else %}
&nbsp;
{% endif %}
</div>
</div>
{% else %}
{% if field.value %}
<div id="markdown">{{ field.value | markdown | safe }}</div>
{% else %}
&nbsp;
{% endif %}
{% endif %}
{% elif not field.value %}
&nbsp;
{% endif %}
{% else %}
<div class="detail-view-field">
<label>{{ field.label }}</label>
<span>
{% if field.field.choices %} {# Display the selected choice text value #}
{% if field.value %}
{% for field_value in field.value|choice_ids %}
{% for id, value in field.field.choices %}
{% if field_value == id %}
{{ value }},
{% endif %}
{% endfor %}
{% endfor %}
{% else %}
&nbsp;
{% endif %}
{% else %}
{% if field.value is not None %}
{{ field.value }}
{% else %}
&nbsp;
{% endif %}
{% endif %}
</span>
</div>
{% endif %}

View File

@ -1,104 +0,0 @@
{% load json %}
{% load markdown %}
{% if not tab.sections %}
<h3>{{ tab.name }}</h3>
{% endif %}
{% for section in tab.sections %}
{% if forloop.first %}
<h3>
{{ tab.name }}
{% for external_link in external_links %}
<span style="font-weight: normal; float: right;">{% include 'icons/external_link.html.j2' with external_link=external_link %}</span>
{% endfor %}
</h3>
{% else %}
<hr />
<h3>{{ section.name }}</h3>
{% endif %}
<div style="align-items:flex-start; align-content: center; display: flexbox; width: 100%">
{% if section.layout == 'single' %}
{% for section_field in section.fields %}
{% for field in form %}
{% if field.name in section_field %}
{% include 'content/field.html.j2' %}
{% endif %}
{% endfor %}
{% endfor %}
{% elif section.layout == 'double' %}
{% if section.left %}
<div style="display: inline; width: 40%; margin: 30px;">
{% for section_field in section.left %}
{% for field in form %}
{% if field.name in section_field %}
{% include 'content/field.html.j2' %}
{% endif %}
{% endfor %}
{% endfor %}
</div>
{% endif %}
{% if section.right %}
<div style="display: inline; width: 40%; margin: 30px; text-align: left;">
{% for section_field in section.right %}
{% for field in form %}
{% if field.name in section_field %}
{% include 'content/field.html.j2' %}
{% endif %}
{% endfor %}
{% endfor %}
</div>
{% endif %}
{% endif %}
{% if forloop.first %}
{% if tab.edit_url %}
<div style="display:block;">
<input type="button" value="Edit" onclick="window.location='{{ tab.edit_url }}';">
</div>
{% endif %}
{% endif %}
</div>
{% endfor %}

View File

@ -1,47 +0,0 @@
{% extends 'base.html.j2' %}
{% block content %}
<div class="content-navigation-tabs">
<button onclick="window.location='{{ form.url_index_view }}';" style="vertical-align: middle; padding: auto; margin: 0px">
<svg xmlns="http://www.w3.org/2000/svg" height="25px" viewBox="0 -960 960 960" width="25px"
style="vertical-align: middle; margin: 0px; padding: 0px border: none; " fill="#6a6e73">
<path d="m313-480 155 156q11 11 11.5 27.5T468-268q-11 11-28 11t-28-11L228-452q-6-6-8.5-13t-2.5-15q0-8 2.5-15t8.5-13l184-184q11-11 27.5-11.5T468-692q11 11 11 28t-11 28L313-480Zm264 0 155 156q11 11 11.5 27.5T732-268q-11 11-28 11t-28-11L492-452q-6-6-8.5-13t-2.5-15q0-8 2.5-15t8.5-13l184-184q11-11 27.5-11.5T732-692q11 11 11 28t-11 28L577-480Z" />
</svg>
Back to {{ form.model_name_plural }}
</button>
{% for key, tab in form.tabs.items %}
{% if forloop.first %}
<button id="defaultOpen" class="content-navigation-tabs-link" onclick="openContentNavigationTab(event, '{{ tab.slug }}')">{{ tab.name }}</button>
{% else %}
<button id="tab-{{ tab.slug }}" class="content-navigation-tabs-link" onclick="openContentNavigationTab(event, '{{ tab.slug }}')">{{ tab.name }}</button>
{% endif %}
{% endfor %}
</div>
{% block tabs %}{% endblock %}
{% if open_tab %}
<script>
document.getElementById("tab-{{ open_tab }}").click();
</script>
{% else %}
<script>
document.getElementById("defaultOpen").click();
</script>
{% endif %}
{% endblock %}

View File

@ -1,12 +0,0 @@
{% extends 'base.html.j2' %}
{% block content %}
<div>
<form method="post" id="dynamic-form">
{% csrf_token %}
{{ form.as_div }}
<input type="submit" value="Submit">
</form>
</div>
{% endblock %}

View File

@ -1,12 +0,0 @@
{% extends 'base.html.j2' %}
{% block content %}
To Do List:
<ul>
<li>{% include 'icons/issue_link.html.j2' with issue=5 %} - Item History</li>
</ul>
{% endblock %}

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M96-144v-648h384v144h384v504H96Zm72-72h240v-72H168v72Zm0-144h240v-72H168v72Zm0-144h240v-72H168v72Zm0-144h240v-72H168v72Zm312 432h312v-360H480v360Zm72-216v-72h168v72H552Zm0 144v-72h168v72H552Z"/></svg>

Before

Width:  |  Height:  |  Size: 274 B

View File

@ -1,12 +0,0 @@
<span class="icon-text add">
<span class="icon-add">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px">
<path d="M440-280h80v-160h160v-80H520v-160h-80v160H280v80h160v160Zm40 200q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Z"/>
</svg>
</span>
{% if icon_link %}
<a href="{{ icon_link }}">{{ icon_text }}</a>
{% else %}
{{ icon_text }}
{% endif %}
</span>

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 2C6.5 2 2 6.5 2 12C2 17.5 6.5 22 12 22C17.5 22 22 17.5 22 12C22 6.5 17.5 2 12 2M16.1 17C15.91 17 15.76 16.9 15.55 16.73L10.39 12.56L8.66 16.9H7.17L11.54 6.39C11.65 6.11 11.89 5.97 12.17 5.97C12.45 5.97 12.67 6.11 12.79 6.39L16.77 15.97C16.81 16.08 16.84 16.19 16.84 16.26C16.83 16.68 16.5 17 16.1 17M12.17 8.11L14.76 14.5L10.85 11.42L12.17 8.11Z" /></svg>

Before

Width:  |  Height:  |  Size: 428 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M280-120q-83 0-141.5-58.5T80-320q0-73 45.5-127.5T240-516v83q-35 12-57.5 43T160-320q0 50 35 85t85 35q50 0 85-35t35-85v-40h235q8-9 19.5-14.5T680-380q25 0 42.5 17.5T740-320q0 25-17.5 42.5T680-260q-14 0-25.5-5.5T635-280H476q-14 69-68.5 114.5T280-120Zm400 0q-56 0-101.5-27.5T507-220h107q14 10 31 15t35 5q50 0 85-35t35-85q0-50-35-85t-85-35q-20 0-37 5.5T611-418L489-621q-21-4-35-20t-14-39q0-25 17.5-42.5T500-740q25 0 42.5 17.5T560-680v8.5q0 3.5-2 8.5l87 146q8-2 17-2.5t18-.5q83 0 141.5 58.5T880-320q0 83-58.5 141.5T680-120ZM280-260q-25 0-42.5-17.5T220-320q0-22 14-38t34-21l94-156q-29-27-45.5-64.5T300-680q0-83 58.5-141.5T500-880q83 0 141.5 58.5T700-680h-80q0-50-35-85t-85-35q-50 0-85 35t-35 85q0 43 26 75.5t66 41.5L337-338q2 5 2.5 9t.5 9q0 25-17.5 42.5T280-260Z"/></svg>

Before

Width:  |  Height:  |  Size: 837 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 16V4H8V16H20M22 16C22 17.1 21.1 18 20 18H8C6.9 18 6 17.1 6 16V4C6 2.9 6.9 2 8 2H20C21.1 2 22 2.9 22 4V16M16 20V22H4C2.9 22 2 21.1 2 20V7H4V20H16M14.2 5C13.3 5 12.6 5.2 12.1 5.6C11.6 6 11.3 6.6 11.3 7.4H13.2C13.2 7.1 13.3 6.9 13.5 6.7C13.7 6.6 13.9 6.5 14.2 6.5C14.5 6.5 14.8 6.6 15 6.8C15.2 7 15.3 7.2 15.3 7.6C15.3 7.9 15.2 8.2 15.1 8.4C15 8.6 14.7 8.8 14.5 9C14 9.3 13.6 9.6 13.5 9.9C13.1 10.1 13 10.5 13 11H15C15 10.7 15 10.4 15.1 10.3C15.2 10.1 15.4 9.9 15.6 9.8C16 9.6 16.4 9.3 16.7 8.9C17 8.4 17.2 8 17.2 7.5C17.2 6.7 16.9 6.1 16.4 5.7C15.9 5.2 15.1 5 14.2 5M13 12V14H15V12H13Z" /></svg>

Before

Width:  |  Height:  |  Size: 666 B

View File

@ -1,8 +0,0 @@
<span class="icon-text change">
<span class="icon-change">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px">
<path d="M483-337q-29 0-56.5-10T378-378q-20-20-31-46.28T336-480q0-9.74.8-18.99.8-9.25 3.2-18.01 2-10-1.66-18.82-3.65-8.83-12.59-12.5-9.75-3.68-18.37.51-8.63 4.19-11.63 14.24Q292-521 290-507.63q-2 13.37-2 27.63 0 38 14.71 73.42Q317.42-371.17 344-344q28 28 64.5 42t75.5 14l-27 27q-7 7.36-7 17.18t7 16.82q7 7 16.82 7t17.18-7l59.79-59.79Q562-298 562-312.18T551-337l-59-60q-7.36-7-17.18-7T458-397q-7 7-7 16.82t7 17.18l25 26Zm-7-287q29.7 0 57.35 10.5Q561-603 582-582q20 20 31 46.28T624-480q0 9-.8 18.5T620-443q-2 10 1.5 19t12.59 12q9.91 3 18.89-1.32 8.99-4.33 12.11-14.71Q669-441 670.5-453.5 672-466 672-480q0-38-15-73.5T615-616q-28-28-65-41.5T474-670l29-29q7-7.36 7-17.18T503-733q-7-7-16.82-7T469-733l-59.79 59.79Q398-662 398-647.82T409-623l60 60q7.36 7 17.18 7t16.82-7q7-7 7-16.82T503-597l-27-27Zm4.28 528Q401-96 331-126t-122.5-82.5Q156-261 126-330.96t-30-149.5Q96-560 126-629.5q30-69.5 82.5-122T330.96-834q69.96-30 149.5-30t149.04 30q69.5 30 122 82.5T834-629.28q30 69.73 30 149Q864-401 834-331t-82.5 122.5Q699-156 629.28-126q-69.73 30-149 30Z"/>
</svg>
</span>
{{ icon_text }}
</span>

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4,1C2.89,1 2,1.89 2,3V7C2,8.11 2.89,9 4,9H1V11H13V9H10C11.11,9 12,8.11 12,7V3C12,1.89 11.11,1 10,1H4M4,3H10V7H4V3M3,12V14H5V12H3M14,13C12.89,13 12,13.89 12,15V19C12,20.11 12.89,21 14,21H11V23H23V21H20C21.11,21 22,20.11 22,19V15C22,13.89 21.11,13 20,13H14M3,15V17H5V15H3M14,15H20V19H14V15M3,18V20H5V18H3M6,18V20H8V18H6M9,18V20H11V18H9Z" /></svg>

Before

Width:  |  Height:  |  Size: 414 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8 17L12 13H15.2C15.6 14.2 16.7 15 18 15C19.7 15 21 13.7 21 12S19.7 9 18 9C16.7 9 15.6 9.8 15.2 11H12L8 7V3H3V8H6L10.2 12L6 16H3V21H8V17Z" /></svg>

Before

Width:  |  Height:  |  Size: 216 B

View File

@ -1,12 +0,0 @@
<span class="icon-text cross">
<span class="icon-cross">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px">
<path d="m480-429 116 116q11 11 25.5 10.5T647-314q11-11 11-25.5t-11-25.46L531-480.5l116-115.54q11-10.96 11-25.46T647-647q-11-11-25.5-11T596-647L480-531 364-647q-11-11-25-11t-25 11q-11 11-11 25.5t10.91 25.5L429-480 313-364q-11 11-10.5 25t11.5 25q11 11 25.5 11t25.41-10.91L480-429Zm.28 333Q401-96 331-126t-122.5-82.5Q156-261 126-330.96t-30-149.5Q96-560 126-629.5q30-69.5 82.5-122T330.96-834q69.96-30 149.5-30t149.04 30q69.5 30 122 82.5T834-629.28q30 69.73 30 149Q864-401 834-331t-82.5 122.5Q699-156 629.28-126q-69.73 30-149 30Z" />
</svg>
</span>
{% if icon_link %}
<a href="{{ icon_link }}">{{ icon_text }}</a>
{% else %}
{{ icon_text }}
{% endif %}
</span>

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M280-120q-33 0-56.5-23.5T200-200v-520h-40v-80h200v-40h240v40h200v80h-40v520q0 33-23.5 56.5T680-120H280Zm400-600H280v520h400v-520ZM360-280h80v-360h-80v360Zm160 0h80v-360h-80v360ZM280-720v520-520Z"/></svg>

Before

Width:  |  Height:  |  Size: 277 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M48-144v-72h864v72H48Zm120-120q-29.7 0-50.85-21.15Q96-306.3 96-336v-408q0-29.7 21.15-50.85Q138.3-816 168-816h624q29.7 0 50.85 21.15Q864-773.7 864-744v408q0 29.7-21.15 50.85Q821.7-264 792-264H168Zm0-72h624v-408H168v408Zm0 0v-408 408Z"/></svg>

Before

Width:  |  Height:  |  Size: 315 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 1L14 6V17L19 12.5V1M21 5V18.5C19.9 18.15 18.7 18 17.5 18C15.8 18 13.35 18.65 12 19.5V6C10.55 4.9 8.45 4.5 6.5 4.5C4.55 4.5 2.45 4.9 1 6V20.65C1 20.9 1.25 21.15 1.5 21.15C1.6 21.15 1.65 21.1 1.75 21.1C3.1 20.45 5.05 20 6.5 20C8.45 20 10.55 20.4 12 21.5C13.35 20.65 15.8 20 17.5 20C19.15 20 20.85 20.3 22.25 21.05C22.35 21.1 22.4 21.1 22.5 21.1C22.75 21.1 23 20.85 23 20.6V6C22.4 5.55 21.75 5.25 21 5M10 18.41C8.75 18.09 7.5 18 6.5 18C5.44 18 4.18 18.19 3 18.5V7.13C3.91 6.73 5.14 6.5 6.5 6.5C7.86 6.5 9.09 6.73 10 7.13V18.41Z" /></svg>

Before

Width:  |  Height:  |  Size: 607 B

View File

@ -1,3 +0,0 @@
<svg viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<path d="M15.6979 7.28711L8.71226 0.3018C8.31016 -0.100594 7.65768 -0.100594 7.25502 0.3018L5.80457 1.75251L7.64462 3.59255C8.07224 3.44815 8.56264 3.54507 8.90339 3.8859C9.2462 4.22884 9.3423 4.72345 9.19416 5.15263L10.9677 6.92595C11.3969 6.77801 11.8917 6.87364 12.2345 7.21692C12.7133 7.69562 12.7133 8.47162 12.2345 8.95072C11.7553 9.42983 10.9795 9.42983 10.5001 8.95072C10.1399 8.59023 10.0508 8.06101 10.2335 7.61726L8.5793 5.96325V10.3157C8.69594 10.3735 8.80613 10.4505 8.90339 10.5475C9.38223 11.0263 9.38223 11.8022 8.90339 12.2817C8.42456 12.7604 7.64815 12.7604 7.16967 12.2817C6.69083 11.8022 6.69083 11.0263 7.16967 10.5475C7.28802 10.4293 7.42507 10.3399 7.5713 10.28V5.88728C7.42507 5.82742 7.28835 5.73874 7.16967 5.61971C6.80701 5.25717 6.71974 4.72481 6.90575 4.27937L5.09177 2.46512L0.301736 7.25474C-0.100579 7.65747 -0.100579 8.30995 0.301736 8.71233L7.28767 15.6977C7.68985 16.1 8.34213 16.1 8.74491 15.6977L15.6979 8.7447C16.1004 8.34225 16.1004 7.68944 15.6979 7.28711"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" ><path d="M478-240q21 0 35.5-14.5T528-290q0-21-14.5-35.5T478-340q-21 0-35.5 14.5T428-290q0 21 14.5 35.5T478-240Zm-36-154h74q0-33 7.5-52t42.5-52q26-26 41-49.5t15-56.5q0-56-41-86t-97-30q-57 0-92.5 30T342-618l66 26q5-18 22.5-39t53.5-21q32 0 48 17.5t16 38.5q0 20-12 37.5T506-526q-44 39-54 59t-10 73Zm38 314q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q134 0 227-93t93-227q0-134-93-227t-227-93q-134 0-227 93t-93 227q0 134 93 227t227 93Zm0-320Z"/></svg>

Before

Width:  |  Height:  |  Size: 654 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M480-60q-72-68-165-104t-195-36v-440q101 0 194 36.5T480-498q73-69 166-105.5T840-640v440q-103 0-195.5 36T480-60Zm0-104q63-47 134-75t146-37v-276q-73 13-143.5 52.5T480-394q-66-66-136.5-105.5T200-552v276q75 9 146 37t134 75Zm0-436q-66 0-113-47t-47-113q0-66 47-113t113-47q66 0 113 47t47 113q0 66-47 113t-113 47Zm0-80q33 0 56.5-23.5T560-760q0-33-23.5-56.5T480-840q-33 0-56.5 23.5T400-760q0 33 23.5 56.5T480-680Zm0-80Zm0 366Z"/></svg>

Before

Width:  |  Height:  |  Size: 499 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M264-792v168-168 624-8.5 8.5-624Zm0 696q-29.7 0-50.85-21.15Q192-138.3 192-168v-624q0-29.7 21.15-50.85Q234.3-864 264-864h312l192 192v198q-18-4-36-5t-36 1v-146H528v-168H264v624h228q6.25 20.08 15.63 37.54Q517-113 529-96H264Zm387-24-51-51 69-69-69-69 51-51 69 69 69-69 51 51-69 69 69 69-51 51-69-69-69 69Z"/></svg>

Before

Width:  |  Height:  |  Size: 384 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m439-240 221-221-54-54-167 167-81-82-55 54 136 136ZM263.72-96Q234-96 213-117.15T192-168v-624q0-29.7 21.15-50.85Q234.3-864 264-864h312l192 192v504q0 29.7-21.16 50.85Q725.68-96 695.96-96H263.72ZM528-624v-168H264v624h432v-456H528ZM264-792v189-189 624-624Z"/></svg>

Before

Width:  |  Height:  |  Size: 335 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M264-96q-29 0-50.5-21.15T192-168v-120h72v120h432v-120h72v120q0 30-21.5 51T696-96H264Zm-72-408v-288q0-29.7 21.5-50.85Q235-864 264-864h312l192 192v168h-72v-120H528v-168H264v288h-72ZM96-360v-72h768v72H96Zm384-144Zm0 216Z"/></svg>

Before

Width:  |  Height:  |  Size: 300 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M264-109q-29.7 0-50.85-21.15Q192-151.3 192-181v-624q0-29.7 21.15-50.85Q234.3-877 264-877h312l192 192v288h-72v-240H528v-168H264v624h336v72H264Zm586 13L744-202v81h-72v-204h204v72h-82l106 106-50 51Zm-586-85v-624 624Z"/></svg>

Before

Width:  |  Height:  |  Size: 296 B

View File

@ -1,6 +0,0 @@
<span class="icon-text issue">
<span class="icon-issue">
<svg xmlns="http://www.w3.org/2000/svg" height="25px" viewBox="0 -960 960 960" width="25px"><path d="M480-144q-60 0-109-32.5T302-264h-74q-15.3 0-25.65-10.29Q192-284.58 192-299.79t10.35-25.71Q212.7-336 228-336h60v-60h-60q-15.3 0-25.65-10.29Q192-416.58 192-431.79t10.35-25.71Q212.7-468 228-468h60v-60h-60q-15.3 0-25.65-10.29Q192-548.58 192-563.79t10.35-25.71Q212.7-600 228-600h74q8-26 25.8-47.09Q345.6-668.18 369-684l-56-56q-11-11-10.5-25.5T314-791q11-11 25-11t25 11l76 75q19.86-5 40.43-5t40.57 5l75-75q11-11 25.67-11 14.66 0 25.33 11 11 11 11 25.5T647-740l-56 56q23 16 40 37t27 47h74q15.3 0 25.65 10.29Q768-579.42 768-564.21t-10.35 25.71Q747.3-528 732-528h-60v60h60q15.3 0 25.65 10.29Q768-447.42 768-432.21t-10.35 25.71Q747.3-396 732-396h-60v60h60q15.3 0 25.65 10.29Q768-315.42 768-300.21t-10.35 25.71Q747.3-264 732-264h-74q-20 55-69 87.5T480-144Zm0-72q48.67 0 83.34-35Q598-286 600-336v-192q2-50-33.5-85t-86-35q-50.5 0-85 35T360-528v192q-1 50 34 85t86 35Zm-36.09-120h71.83q15.26 0 25.76-10.29 10.5-10.29 10.5-25.5t-10.32-25.71Q531.35-408 516.09-408h-71.83q-15.26 0-25.76 10.29-10.5 10.29-10.5 25.5t10.32 25.71q10.33 10.5 25.59 10.5Zm0-120h71.83q15.26 0 25.76-10.29 10.5-10.29 10.5-25.5t-10.32-25.71Q531.35-528 516.09-528h-71.83q-15.26 0-25.76 10.29-10.5 10.29-10.5 25.5t10.32 25.71q10.33 10.5 25.59 10.5ZM480-430Z"/></svg>
</span>
<a href="https://github.com/nofusscomputing/centurion_erp/issues/{{ issue }}" target="_blank"> see #{{ issue }}</a>
</span>

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M288-192H168q-30 0-51-21.16t-21-50.88v-432.24Q96-726 117.15-747T168-768h624v72H168v432h120v72Zm144-120q20 0 34-14t14-34q0-20-14-34t-34-14q-20 0-34 14t-14 34q0 20 14 34t34 14Zm-72 120v-72q-22-17-35-42.24-13-25.23-13-53.76 0-28.53 13-53.76 13-25.24 35-42.43V-528h144v72q22 17 35 42.24 13 25.23 13 53.76 0 28.53-13 53.76-13 25.24-35 42.43V-192H360Zm468 0H636q-15.3 0-25.65-10.35Q600-212.7 600-228v-336q0-15.3 10.35-25.65Q620.7-600 636-600h192q15.3 0 25.65 10.35Q864-579.3 864-564v336q0 15.3-10.35 25.65Q843.3-192 828-192Zm-156-72h120v-264H672v264Zm0 0h120-120Z"/></svg>

Before

Width:  |  Height:  |  Size: 640 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2 4.6V9.4C2 10.3 2.5 11 3.2 11H20.9C21.5 11 22.1 10.3 22.1 9.4V4.6C22 3.7 21.5 3 20.8 3H3.2C2.5 3 2 3.7 2 4.6M10 8V6H9V8H10M5 8H7V6H5V8M20 9H4V5H20V9M2 14.6V19.4C2 20.3 2.5 21 3.2 21H20.9C21.5 21 22.1 20.3 22.1 19.4V14.6C22.1 13.7 21.6 13 20.9 13H3.2C2.5 13 2 13.7 2 14.6M10 18V16H9V18H10M5 18H7V16H5V18M20 19H4V15H20V19Z" /></svg>

Before

Width:  |  Height:  |  Size: 401 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="#EA3323"><path d="M256-200h447l-84-84q-29 21-64.5 32.5T480-240q-39 0-74.5-12T341-285l-85 85Zm-56-57 84-84q-21-29-32.5-64.5T240-480q0-39 12-74.5t33-64.5l-85-85v447Zm142-142 82-81-82-81q-11 18-16.5 38t-5.5 43q0 23 5.5 43t16.5 38Zm138 79q23 0 43-5.5t38-16.5l-81-82-82 82q18 11 38.5 16.5T480-320Zm0-217 81-81q-18-11-38-16.5t-43-5.5q-23 0-43 5.5T399-618l81 81Zm138 138q11-18 16.5-38t5.5-43q0-23-5.5-43.5T618-562l-81 81 81 82Zm142 142v-447l-85 85q21 29 33 64.5t12 74.5q0 39-11.5 74.5T676-341l84 84ZM619-675l85-85H257l84 84q29-21 64.5-32.5T480-720q39 0 74.5 12t64.5 33ZM200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v560q0 33-23.5 56.5T760-120H200Z"/></svg>

Before

Width:  |  Height:  |  Size: 761 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M389.33-343.33 480-432l90.67 88.67L619.33-392l-90-88.67 90-89.33-48.66-48.67L480-530l-90.67-88.67L340.67-570l90 89.33-90 88.67 48.66 48.67ZM480-80.67q-139.67-35-229.83-161.5Q160-368.67 160-520.67v-240l320-120 320 120v240q0 152-90.17 278.5Q619.67-115.67 480-80.67Zm0-69.33q111.33-36.33 182.33-139.67 71-103.33 71-231v-193.66L480-809.67l-253.33 95.34v193.66q0 127.67 71 231Q368.67-186.33 480-150Zm0-330Z"/></svg>

Before

Width:  |  Height:  |  Size: 484 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m436-347 228-228-42-41-183 183-101-101-44 44 142 143Zm44 266q-140-35-230-162.5T160-523v-238l320-120 320 120v238q0 152-90 279.5T480-81Zm0-62q115-38 187.5-143.5T740-523v-196l-260-98-260 98v196q0 131 72.5 236.5T480-143Zm0-337Z"/></svg>

Before

Width:  |  Height:  |  Size: 306 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M480-81q-140-35-230-162.5T160-523v-238l320-120 320 120v238q0 152-90 279.5T480-81Zm0-62q115-38 187.5-143.5T740-523v-196l-260-98-260 98v196q0 131 72.5 236.5T480-143Zm0-337Zm0 195q15 0 26-11t11-26q0-15-11-26t-26-11q-15 0-26 11t-11 26q0 15 11 26t26 11Zm-25-124h50q0-15 1.5-25t5.5-18q4-8 11-16t18-19q24-22 36-45t12-46q0-41-30.5-69T483-675q-38 0-69 21t-42 55l45 18q8-21 25.5-33.5T483-627q23 0 39.5 15t16.5 36q0 15-8.5 29.5T503-515q-17 15-25 25.5T465-468q-5 12-7.5 26.5T455-409Z"/></svg>

Before

Width:  |  Height:  |  Size: 554 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M479.79-336q15.21 0 25.71-10.29t10.5-25.5q0-15.21-10.29-25.71t-25.5-10.5q-15.21 0-25.71 10.29t-10.5 25.5q0 15.21 10.29 25.71t25.5 10.5ZM444-480h72v-192h-72v192Zm36 384q-135-33-223.5-152.84Q168-368.69 168-515v-229l312-120 312 120v229q0 146.31-88.5 266.16Q615-129 480-96Zm0-75q104-32.25 172-129t68-215v-180l-240-92-240 92v180q0 118.25 68 215t172 129Zm0-308Z"/></svg>

Before

Width:  |  Height:  |  Size: 438 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21.7 18.6V17.6L22.8 16.8C22.9 16.7 23 16.6 22.9 16.5L21.9 14.8C21.9 14.7 21.7 14.7 21.6 14.7L20.4 15.2C20.1 15 19.8 14.8 19.5 14.7L19.3 13.4C19.3 13.3 19.2 13.2 19.1 13.2H17.1C16.9 13.2 16.8 13.3 16.8 13.4L16.6 14.7C16.3 14.9 16.1 15 15.8 15.2L14.6 14.7C14.5 14.7 14.4 14.7 14.3 14.8L13.3 16.5C13.3 16.6 13.3 16.7 13.4 16.8L14.5 17.6V18.6L13.4 19.4C13.3 19.5 13.2 19.6 13.3 19.7L14.3 21.4C14.4 21.5 14.5 21.5 14.6 21.5L15.8 21C16 21.2 16.3 21.4 16.6 21.5L16.8 22.8C16.9 22.9 17 23 17.1 23H19.1C19.2 23 19.3 22.9 19.3 22.8L19.5 21.5C19.8 21.3 20 21.2 20.3 21L21.5 21.4C21.6 21.4 21.7 21.4 21.8 21.3L22.8 19.6C22.9 19.5 22.9 19.4 22.8 19.4L21.7 18.6M18 19.5C17.2 19.5 16.5 18.8 16.5 18S17.2 16.5 18 16.5 19.5 17.2 19.5 18 18.8 19.5 18 19.5M12.3 22H3C1.9 22 1 21.1 1 20V4C1 2.9 1.9 2 3 2H21C22.1 2 23 2.9 23 4V13.1C22.4 12.5 21.7 12 21 11.7V6H3V20H11.3C11.5 20.7 11.8 21.4 12.3 22Z" /></svg>

Before

Width:  |  Height:  |  Size: 958 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="m403-96-22-114q-23-9-44.5-21T296-259l-110 37-77-133 87-76q-2-12-3-24t-1-25q0-13 1-25t3-24l-87-76 77-133 110 37q19-16 40.5-28t44.5-21l22-114h154l22 114q23 9 44.5 21t40.5 28l110-37 77 133-87 76q2 12 3 24t1 25q0 13-1 25t-3 24l87 76-77 133-110-37q-19 16-40.5 28T579-210L557-96H403Zm59-72h36l19-99q38-7 71-26t57-48l96 32 18-30-76-67q6-17 9.5-35.5T696-480q0-20-3.5-38.5T683-554l76-67-18-30-96 32q-24-29-57-48t-71-26l-19-99h-36l-19 99q-38 7-71 26t-57 48l-96-32-18 30 76 67q-6 17-9.5 35.5T264-480q0 20 3.5 38.5T277-406l-76 67 18 30 96-32q24 29 57 48t71 26l19 99Zm18-168q60 0 102-42t42-102q0-60-42-102t-102-42q-60 0-102 42t-42 102q0 60 42 102t102 42Zm0-144Z"/></svg>

Before

Width:  |  Height:  |  Size: 731 B

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M816-672v456q0 29.7-21.15 50.85Q773.7-144 744-144H216q-29.7 0-50.85-21.15Q144-186.3 144-216v-528q0-29.7 21.15-50.85Q186.3-816 216-816h456l144 144Zm-72 30L642-744H216v528h528v-426ZM480-252q45 0 76.5-31.5T588-360q0-45-31.5-76.5T480-468q-45 0-76.5 31.5T372-360q0 45 31.5 76.5T480-252ZM264-552h336v-144H264v144Zm-48-77v413-528 115Z"/></svg>

Before

Width:  |  Height:  |  Size: 410 B

View File

@ -1,12 +0,0 @@
<span class="icon-text success">
<span class="icon-success">
<svg xmlns="http://www.w3.org/2000/svg" height="20px" viewBox="0 -960 960 960" width="20px">
<path class="tick" d="m424-408-86-86q-11-11-28-11t-28 11q-11 11-11 28t11 28l114 114q12 12 28 12t28-12l226-226q11-11 11-28t-11-28q-11-11-28-11t-28 11L424-408Zm56 328q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Z"></path>
</svg>
</span>
{% if icon_link %}
<a href="{{ icon_link }}">{{ icon_text }}</a>
{% else %}
{{ icon_text }}
{% endif %}
</span>

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path d="M660-160h40v-160h-40v160Zm20-200q8 0 14-6t6-14q0-8-6-14t-14-6q-8 0-14 6t-6 14q0 8 6 14t14 6ZM200-800v640-640 200-200Zm80 400h147q11-23 25.5-43t32.5-37H280v80Zm0 160h123q-3-20-3-40t3-40H280v80ZM200-80q-33 0-56.5-23.5T120-160v-640q0-33 23.5-56.5T200-880h320l240 240v92q-19-6-39-9t-41-3v-40H480v-200H200v640h227q11 23 25.5 43T485-80H200Zm480-400q83 0 141.5 58.5T880-280q0 83-58.5 141.5T680-80q-83 0-141.5-58.5T480-280q0-83 58.5-141.5T680-480Z"/></svg>

Before

Width:  |  Height:  |  Size: 522 B

View File

@ -1,86 +0,0 @@
{% block navigation %}
{% for group in nav_items %}
<style>
span.navigation_icon {
display: inline-block;
line-height: 30px;
align-items: center;
vertical-align: middle;
/*padding: auto;*/
margin: 0px;
fill: #fff;
width: 20px;
height: 20px;
/*vertical-align: middle;*/
/*margin: 0px;*/
/*padding: 0px;*/
border: none;
border-radius: 11px;
}
</style>
<button class="collapsible{% if group.is_active %} active{% endif %}">
<span class="navigation_icon">
{% if group.name == 'Assistance' %}
{% include 'icons/assistance.svg' %}
{% elif group.name == 'Access' %}
{% include 'icons/access.svg' %}
{% elif group.name == 'Config Management' %}
{% include 'icons/ansible.svg' %}
{% elif group.name == 'ITAM' %}
{% include 'icons/itam.svg' %}
{% elif group.name == 'ITIM' %}
{% include 'icons/itim.svg' %}
{% elif group.name == 'Settings' %}
{% include 'icons/settings.svg' %}
{% elif group.name == 'Project Management' %}
{% include 'icons/project.svg' %}
{% endif %}
</span>
{{ group.name }}
</button>
<div class="content"{% if group.is_active %} style="max-height:inherit" {% endif %}>
<ul>
{% for group_urls in group.urls %}
<li{% if group_urls.is_active %} class="active"{% endif %} style="padding-left: 40px">
<span class="navigation_icon">
{% if group_urls.name == 'Clusters' %}
{% include 'icons/clusters.svg' %}
{% elif group_urls.name == 'Devices' %}
{% include 'icons/devices.svg' %}
{% elif group_urls.name == 'Knowledge Base' %}
{% include 'icons/information.svg' %}
{% elif group_urls.name == 'Services' %}
{% include 'icons/service.svg' %}
{% elif group_urls.name == 'Software' %}
{% include 'icons/software.svg' %}
{% elif group_urls.name == 'Groups' %}
{% include 'icons/config_management.svg' %}
{% endif %}
</span>
<a href="{{ group_urls.url }}">{{ group_urls.name }}</a>
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
<script>
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function () {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.maxHeight) {
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
</script>
{% endblock %}

View File

@ -1,13 +0,0 @@
{% extends 'base.html.j2' %}
{% block title %}Change Password{% endblock %}
{% block content %}
<div>
<form action="" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
</div>
{% endblock %}

View File

@ -8,9 +8,6 @@ about: https://gitlab.com/nofusscomputing/infrastructure/configuration-managemen
Viewsets are used by Centurion ERP for each of the API views.
!!! info
Centurion release v1.3.0 added a feature lock to **ALL** Views and the current API. From this release, there is a new API at endpoint `api/v2`. As such we will only be using DRF `ViewSets`. This is required as the UI is being separated from the Centurion Codebase to its own repository. This means that Centurion will become an API only codebase. Release 2.0.0 will remove the current UI and api from Centurion. [See #](https://github.com/nofusscomputing/centurion_erp/issues/343) for details.
## Requirements

View File

@ -6,7 +6,7 @@ template: project.html
about: https://gitlab.com/nofusscomputing/infrastructure/configuration-management/centurion_erp
---
An api is available for this application and can be viewed at endpoint `/api/`. Documentation specific to each of the endpoints can be found within the swagger UI at endpoint `api/swagger/`.
An api is available for this application and can be viewed at endpoint `/api/`. Documentation specific to each of the endpoints can be found within the swagger UI at endpoint `/api/v2/docs`.
## Features
@ -15,6 +15,8 @@ An api is available for this application and can be viewed at endpoint `/api/`.
- Swagger UI
All models can be found and accessed via the API. To locate a model click on it's module name then on page load you will see the model name in the list. Clicking on the model will enable you to work with it.
## Device Inventory
@ -23,31 +25,4 @@ You can [inventory](itam/device.md#inventory) your devices and upload them to th
## Swagger UI
The swagger UI is included within this application and can be found at endpoint `/api/swagger` on your server. This UI has been used to document the API.
## Organizations
- url `/api/organization`, `HTTP/GET` view organizations
- url `/api/organization`, `HTTP/POST` create an organization
- url `/api/organization/<organization id>`, `HTTP/GET` view an organization
- url `/api/organization/<organization id>`, `HTTP/PATCH` edit an organization
- url `/api/organization/<organization id>`, `HTTP/DELETE` delete an organization
## Teams
- url `/api/organization/<organization id>/team`, `HTTP/GET` view teams within org
- url `/api/organization/<organization id>/team`, `HTTP/POST` create team in org
- url `/api/organization/<organization id>/team/<team id>`, `HTTP/GET` view a team in org
- url `/api/organization/<organization id>/team/<team id>`, `HTTP/PATCH` edit team in org
- url `/api/organization/<organization id>/team/<team id>`, `HTTP/DELETE` delete team in org
### Team Permissions
- url `/api/organization/<organization id>/team/<team id>/permissions`, `HTTP/POST` = replace permissions with those in body
- url `/api/organization/<organization id>/team/<team id>/permissions`, `HTTP/PATCH` = amend permissions to include those in body
- url `/api/organization/<organization id>/team/<team id>/permissions`, `HTTP/DELETE` = delete ALL permissions
HTTP/POST or HTTP/PATCH with list of permission in format `<module name>.<permission>_<model>`. i.e for adding a itam device permission would be `itam.add_device`. if the method is post only the permissions in the post request will remain, the others will be deleted. If method is patch, those in request body will be added.
The swagger UI is included within this application and can be found at endpoint `/api/v2/docs` on your server. This UI has been used to document the API.

View File

@ -1171,7 +1171,7 @@ markers = [
"module_settings: Selects all tests from module settings.",
"note_models: Selects all centurion model note models",
"permissions: selects all permission related tests.",
"regressopm: selects all tests for regression.",
"regression: selects all tests for regression.",
"serializer: Selects all serializer tests",
"tenancy_models: Selects Tenancy models.",
"unit: Selects all Unit Tests.",