perf: labels 支持颜色

pull/13378/head
ibuler 2024-06-04 19:08:16 +08:00
parent 0b65e3ffda
commit 050ddc88f2
7 changed files with 58 additions and 20 deletions

View File

@ -113,7 +113,10 @@ class LabelRelatedField(serializers.RelatedField):
def to_representation(self, value): def to_representation(self, value):
if value is None: if value is None:
return value return value
return str(value.label) label = value.label
if not label:
return None
return {'id': label.id, 'name': label.name, 'value': label.value, 'color': label.color}
def to_internal_value(self, data): def to_internal_value(self, data):
from labels.models import LabeledResource, Label from labels.models import LabeledResource, Label

View File

@ -79,7 +79,7 @@
"Aliyun": "Alibaba cloud", "Aliyun": "Alibaba cloud",
"All": "All", "All": "All",
"AllAccountTip": "All accounts already added on the asset", "AllAccountTip": "All accounts already added on the asset",
"AllAccounts": "All", "AllAccounts": "Existing accounts",
"AllClickRead": "Mark all as read", "AllClickRead": "Mark all as read",
"AllMembers": "All members", "AllMembers": "All members",
"AllowInvalidCert": "Ignore certificate check", "AllowInvalidCert": "Ignore certificate check",
@ -379,6 +379,7 @@
"DefaultDatabase": "Default database", "DefaultDatabase": "Default database",
"DefaultPort": "Default port", "DefaultPort": "Default port",
"Delete": "Delete", "Delete": "Delete",
"WeekAdd": "Weekly add",
"DeleteConfirmMessage": "Deletion is irreversible, do you wish to continue?", "DeleteConfirmMessage": "Deletion is irreversible, do you wish to continue?",
"DeleteErrorMsg": "Delete failed", "DeleteErrorMsg": "Delete failed",
"DeleteNode": "Delete node", "DeleteNode": "Delete node",
@ -656,7 +657,7 @@
"LoginSSHKeySetting": "Login SSH Key", "LoginSSHKeySetting": "Login SSH Key",
"LoginSucceeded": "Login successful", "LoginSucceeded": "Login successful",
"LoginTitleTip": "Note: it will be displayed on the enterprise edition user ssh login koko login page (e.g.: welcome to use jumpserver open source bastion)", "LoginTitleTip": "Note: it will be displayed on the enterprise edition user ssh login koko login page (e.g.: welcome to use jumpserver open source bastion)",
"LoginUserRanking": "Login account ranking", "LoginUserRanking": "Login user ranking",
"LoginUserToday": "Users logged today", "LoginUserToday": "Users logged today",
"LoginUsers": "Active account", "LoginUsers": "Active account",
"LogoIndexTip": "Tip: it will be displayed in the upper left corner of the page (recommended image size: 185px*55px)", "LogoIndexTip": "Tip: it will be displayed in the upper left corner of the page (recommended image size: 185px*55px)",
@ -670,7 +671,7 @@
"MFAOfUserFirstLoginUserGuidePage": "In order to protect your and the company's security, please carefully safeguard important sensitive information such as your account, password, and key (for example, set a complex password, and enable multi-factor authentication) <br/> personal information such as email, mobile number, and wechat are only used for user authentication and platform internal message notifications.", "MFAOfUserFirstLoginUserGuidePage": "In order to protect your and the company's security, please carefully safeguard important sensitive information such as your account, password, and key (for example, set a complex password, and enable multi-factor authentication) <br/> personal information such as email, mobile number, and wechat are only used for user authentication and platform internal message notifications.",
"MailRecipient": "Email recipient", "MailRecipient": "Email recipient",
"MailSend": "Sending", "MailSend": "Sending",
"ManualAccount": "Manual accounts", "ManualAccount": "Manual account",
"ManualAccountTip": "Manual input of username/password upon login", "ManualAccountTip": "Manual input of username/password upon login",
"ManyChoose": "Select multiple", "ManyChoose": "Select multiple",
"MarkAsRead": "Mark as read", "MarkAsRead": "Mark as read",
@ -861,7 +862,7 @@
"QuickJob": "Adhoc", "QuickJob": "Adhoc",
"QuickUpdate": "Quick update", "QuickUpdate": "Quick update",
"Radius": "Radius", "Radius": "Radius",
"Ranking": "Ranking", "Ranking": "Rank",
"RazorNotSupport": "Rdp client session, monitoring not supported", "RazorNotSupport": "Rdp client session, monitoring not supported",
"ReLogin": "Login again", "ReLogin": "Login again",
"ReLoginTitle": "Current third-party login user (cas/saml), not bound to mfa and does not support password verification, please login again.", "ReLoginTitle": "Current third-party login user (cas/saml), not bound to mfa and does not support password verification, please login again.",
@ -971,8 +972,8 @@
"SSHPort": "SSH Port", "SSHPort": "SSH Port",
"SSHSecretKey": "SSH Key", "SSHSecretKey": "SSH Key",
"SafeCommand": "Secure command", "SafeCommand": "Secure command",
"SameAccount": "Same", "SameAccount": "Same account",
"SameAccountTip": "Accounts with the same username as authorized users", "SameAccountTip": "Account with the same username as authorized users",
"SameTypeAccountTip": "An account with the same username and key type already exists", "SameTypeAccountTip": "An account with the same username and key type already exists",
"Saturday": "Sat", "Saturday": "Sat",
"Save": "Save", "Save": "Save",
@ -1059,7 +1060,7 @@
"SourceIP": "Source address", "SourceIP": "Source address",
"SourcePort": "Source port", "SourcePort": "Source port",
"Spec": "Specific", "Spec": "Specific",
"SpecAccount": "Specified", "SpecAccount": "Specified accounts",
"SpecAccountTip": "Specify username to choose authorized account", "SpecAccountTip": "Specify username to choose authorized account",
"SpecialSymbol": "Special char", "SpecialSymbol": "Special char",
"SpecificInfo": "Special information", "SpecificInfo": "Special information",

View File

@ -674,7 +674,7 @@
"MenuAccounts": "账号管理", "MenuAccounts": "账号管理",
"MenuAcls": "访问控制", "MenuAcls": "访问控制",
"MenuAssets": "资产管理", "MenuAssets": "资产管理",
"MenuMore": "更多...", "MenuMore": "其它",
"MenuPermissions": "授权管理", "MenuPermissions": "授权管理",
"MenuUsers": "用户管理", "MenuUsers": "用户管理",
"Message": "消息", "Message": "消息",

View File

@ -0,0 +1,31 @@
# Generated by Django 4.1.13 on 2024-06-04 03:50
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("labels", "0001_initial"),
]
operations = [
migrations.AddField(
model_name="label",
name="color",
field=models.CharField(
blank=True, default="", max_length=32, verbose_name="Color"
),
),
migrations.AlterField(
model_name="labeledresource",
name="label",
field=models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="labeled_resources",
to="labels.label",
verbose_name="Tag",
),
),
]

View File

@ -11,6 +11,9 @@ class Label(JMSOrgBaseModel):
name = models.CharField(max_length=64, verbose_name=_("Name"), db_index=True) name = models.CharField(max_length=64, verbose_name=_("Name"), db_index=True)
value = models.CharField(max_length=64, unique=False, verbose_name=_("Value")) value = models.CharField(max_length=64, unique=False, verbose_name=_("Value"))
internal = models.BooleanField(default=False, verbose_name=_("Internal")) internal = models.BooleanField(default=False, verbose_name=_("Internal"))
color = models.CharField(
max_length=32, default="", blank=True, verbose_name=_("Color")
)
class Meta: class Meta:
unique_together = [("name", "value", "org_id")] unique_together = [("name", "value", "org_id")]

View File

@ -14,8 +14,8 @@ class LabelSerializer(BulkOrgResourceModelSerializer):
class Meta: class Meta:
model = Label model = Label
fields = [ fields = [
'id', 'name', 'value', 'res_count', 'comment', 'id', 'name', 'value', 'color', 'res_count',
'date_created', 'date_updated' 'comment', 'date_created', 'date_updated'
] ]
read_only_fields = ('date_created', 'date_updated', 'res_count') read_only_fields = ('date_created', 'date_updated', 'res_count')
extra_kwargs = { extra_kwargs = {

View File

@ -1,17 +1,17 @@
# Generated by Django 4.1.13 on 2024-05-09 03:16 # Generated by Django 4.1.13 on 2024-05-09 03:16
import uuid
import django.contrib.auth.models
import django.utils.timezone
from django.conf import settings
from django.contrib.auth.hashers import make_password
from django.db import migrations, models
import common.db.fields import common.db.fields
import common.db.models import common.db.models
from django.contrib.auth.hashers import make_password
import common.utils.django import common.utils.django
from django.conf import settings
import django.contrib.auth.models
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import users.models.user import users.models.user
import uuid
def add_default_group(apps, schema_editor): def add_default_group(apps, schema_editor):
@ -62,7 +62,7 @@ class Migration(migrations.Migration):
('avatar', models.ImageField(null=True, upload_to='avatar', verbose_name='Avatar')), ('avatar', models.ImageField(null=True, upload_to='avatar', verbose_name='Avatar')),
('wechat', common.db.fields.EncryptCharField(blank=True, max_length=128, verbose_name='Wechat')), ('wechat', common.db.fields.EncryptCharField(blank=True, max_length=128, verbose_name='Wechat')),
('phone', common.db.fields.EncryptCharField(blank=True, max_length=128, null=True, verbose_name='Phone')), ('phone', common.db.fields.EncryptCharField(blank=True, max_length=128, null=True, verbose_name='Phone')),
('mfa_level', models.SmallIntegerField(choices=[(0, 'Disable'), (1, 'Enable'), (2, 'Force enable')], default=0, verbose_name='MFA')), ('mfa_level', models.SmallIntegerField(choices=[(0, "Disabled"), (1, "Enabled"), (2, "Force enabled")], default=0, verbose_name='MFA')),
('otp_secret_key', common.db.fields.EncryptCharField(blank=True, max_length=128, null=True, verbose_name='OTP secret key')), ('otp_secret_key', common.db.fields.EncryptCharField(blank=True, max_length=128, null=True, verbose_name='OTP secret key')),
('private_key', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Private key')), ('private_key', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Private key')),
('public_key', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Public key')), ('public_key', common.db.fields.EncryptTextField(blank=True, null=True, verbose_name='Public key')),