Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI update #43

Merged
merged 4 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/calculation/hostname_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
class HostnameGenerator < Patterns::Calculation
private
def result
subject.virtual_machine = virtual_machine
hostname_sequence_suffix = '{{ seq }}' if virtual_machine.clustered?
hostname_team_suffix = '{{ team_nr_str }}' if virtual_machine.numbered_actor && (!nic || !nic.network&.numbered?)

Expand All @@ -21,7 +22,7 @@ def result
end

def virtual_machine
subject.virtual_machine
options[:vm] || subject.virtual_machine
end

def nic
Expand Down
2 changes: 2 additions & 0 deletions app/calculation/liquid_range_substitution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ def numbering_actor
subject.network.actor
when VirtualMachine
vm_numbering_source(subject)
when CustomizationSpec
vm_numbering_source(subject.virtual_machine)
else
subject.actor
end
Expand Down
18 changes: 18 additions & 0 deletions app/components/actor_avatar_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

class ActorAvatarComponent < ViewComponent::Base
def initialize(actor:)
@actor = actor
end

private
def attributes
{
class: helpers.actor_color_classes(@actor),
data: {
controller: 'tippy',
tooltip: @actor.name
}
}
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
%figure.rounded-full.inline-block.text-xs.leading-8.w-8.h-8.text-center.inline-block{attributes}= @actor.initials
2 changes: 1 addition & 1 deletion app/components/actor_chip_component.haml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
%span.rounded-full.px-3.py-1.items-center.whitespace-nowrap{class: css_classes}
%span.rounded-full.px-3.py-1.whitespace-nowrap{class: css_classes}
= content
= @text || @actor.name
5 changes: 4 additions & 1 deletion app/components/chip_component.html.haml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
%span.text-sm.rounded-md.px-3.py-0.bg-cyan-200.text-cyan-800.dark:bg-cyan-700.dark:text-cyan-300{title: @name}= @name.truncate(16)
%span.text-xs.rounded-md.px-2.inline-flex.items-center.gap-x-1{title: @name, class: color_classes + ' py-0.5'}
- if @icon
%i.fas{class: "fa-#{@icon}"}
= @name
9 changes: 8 additions & 1 deletion app/components/chip_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
class ChipComponent < ViewComponent::Base
with_collection_parameter :name

def initialize(name:)
def initialize(name:, icon: nil, flavor: 'stone')
@name = name
@flavor = flavor
@icon = icon
end

private
def color_classes
"bg-#{@flavor}-200 text-#{@flavor}-800 dark:bg-#{@flavor}-700 dark:text-#{@flavor}-300"
end
end
2 changes: 1 addition & 1 deletion app/components/liquid_address_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ def render?

private
def template_text
AddressValues.result_for(@object) || UnsubstitutedAddress.result_for(@object)
AddressValues.result_for(@object) || UnsubstitutedAddress.result_for(@object) || 'N/A or dynamic'
end
end
11 changes: 10 additions & 1 deletion app/components/liquid_fqdn_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,15 @@
class LiquidFQDNComponent < LiquidTooltipSnippetComponent
private
def template_text
HostnameGenerator.result_for(@object.host_spec).fqdn
HostnameGenerator.result_for(spec, *options).fqdn
end

def spec
case @object
when CustomizationSpec
@object
when VirtualMachine
@object.host_spec
end
end
end
7 changes: 0 additions & 7 deletions app/components/liquid_text_component.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
# frozen_string_literal: true

class LiquidTextComponent < LiquidTooltipSnippetComponent
attr_reader :actor

def initialize(object:, actor:)
@object = object
@actor = actor
end

private
def template_text
@object
Expand Down
7 changes: 5 additions & 2 deletions app/components/liquid_tooltip_snippet_component.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
# frozen_string_literal: true

class LiquidTooltipSnippetComponent < ViewComponent::Base
def initialize(object:)
attr_reader :options

def initialize(options = {}, object:)
@object = object
@options = options
end

def call
Expand All @@ -13,7 +16,7 @@ def call
{
data: {
controller: 'tippy',
tooltip: LiquidRangeSubstitution.result_for(@object, node: variable_node, actor: @actor)
tooltip: LiquidRangeSubstitution.result_for(@object, node: variable_node, actor: options[:actor])
}
}
)
Expand Down
2 changes: 1 addition & 1 deletion app/components/network_interface_form_component.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
%i.fas.fa-cloud-upload-alt.text-sm
- if network_interface.connection?
.flex.items-center.justify-center.rounded-full.bg-orange-200.text-orange-800.w-7.h-7{title: 'Connection interface'}
%i.fas.fa-cogs.text-sm
%i.fas.fa-satellite-dish.text-sm

- if network_interface.persisted?
= form_with(url: [network_interface.exercise, network_interface.virtual_machine, network_interface], method: :delete, data: { turbo_confirm: 'Are you sure?' }) do |form|
Expand Down
2 changes: 1 addition & 1 deletion app/components/search_component/search_component.html.haml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.relative.z-10{data: {action: 'keydown.esc@window->search#close'}, tabindex: "-1"}
.relative.z-50{data: {action: 'keydown.esc@window->search#close'}, tabindex: "-1"}
.hidden.fixed.inset-0.z-40.overflow-y-auto.flex.items-center.justify-center{"class" => "bg-gray-900/50 dark:bg-gray-900/80","data-action" => "click->search#closeBackground", "data-search-target" => "background", "data-transition-enter" => "transition-all ease-in-out duration-300", "data-transition-enter-from" => "bg-opacity-0", "data-transition-enter-to" => "bg-opacity-80", "data-transition-leave" => "transition-all ease-in-out duration-300", "data-transition-leave-from" => "bg-opacity-80", "data-transition-leave-to" => "bg-opacity-0"}
.bg-white.rounded.shadow-lg.max-h-screen.w-full.max-w-5xl.relative{data: {"search-target" => 'container'}}
= form_with(url: search_path, class: 'border-b border-gray-200', data: {search_target: 'form'}) do |f|
Expand Down
18 changes: 13 additions & 5 deletions app/controllers/virtual_machines_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ class VirtualMachinesController < ApplicationController

def index
@virtual_machines = policy_scope(@exercise.virtual_machines)
.includes({ customization_specs: [:capabilities, :tags] })
.includes({ connection_nic: { addresses: [:address_pool] } })
.preload(
:actor, :operating_system, :system_owner,
:connection_nic, :exercise,
network_interfaces: [
{ network: [:actor, :exercise] }
]
:actor, :numbered_by,
:host_spec, :operating_system, :system_owner,
connection_nic: [:addresses],
)
.order(:name)

Expand Down Expand Up @@ -54,6 +54,14 @@ def show
authorize @virtual_machine
end

def address_preview
@virtual_machine ||= @exercise
.virtual_machines
.find(params[:id])

authorize @virtual_machine, :show?
end

def update
@virtual_machine.numbered_by = get_numbered
@virtual_machine.assign_attributes(virtual_machine_params)
Expand Down
24 changes: 24 additions & 0 deletions app/javascript/controllers/darkmode_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Controller } from "@hotwired/stimulus";

export default class extends Controller {
static values = {
isDark: { type: Boolean },
};
static targets = ["input"];

connect() {
this.isDarkValue = document.documentElement.classList.contains("dark");
this.setInputState();
}

setInputState() {
this.inputTarget.checked = this.isDarkValue;
document.documentElement.classList.toggle("dark", this.isDarkValue);
}

flipMode() {
this.isDarkValue = !this.isDarkValue;
localStorage.theme = this.isDarkValue ? "dark" : "light";
this.setInputState();
}
}
2 changes: 2 additions & 0 deletions app/javascript/controllers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const controllers = import.meta.glob("./**/*_controller.js", { eager: true });
registerControllers(application, controllers);

import { Dropdown, Modal } from "tailwindcss-stimulus-components";
import Clipboard from "stimulus-clipboard";

application.register("dropdown", Dropdown);
application.register("modal", Modal);
application.register("clipboard", Clipboard);
23 changes: 20 additions & 3 deletions app/javascript/src/fonts.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
faBook,
faFlask,
faBox,
faCogs,
faSatelliteDish,
faClipboard,
faCopy,
faClone,
faAnglesRight,
Expand All @@ -21,11 +22,15 @@ import {
faAngleDoubleRight,
faRightFromBracket,
faRightToBracket,
faSquareCaretDown,
faRotateRight,
faHistory,
faSearch,
faUpRightFromSquare,
faIdBadge,
faUserTag,
faTags,
faFileLines,
faKey,
faLayerGroup,
faProjectDiagram,
Expand All @@ -39,7 +44,12 @@ import {
faCircleQuestion,
} from "@fortawesome/free-solid-svg-icons";

import { faUbuntu, faWindows } from "@fortawesome/free-brands-svg-icons";
import {
faUbuntu,
faDebian,
faLinux,
faWindows,
} from "@fortawesome/free-brands-svg-icons";

// Make sure this is before any other `fontawesome` API calls
config.autoAddCss = false;
Expand All @@ -51,7 +61,8 @@ library.add(
faBook,
faFlask,
faBox,
faCogs,
faSatelliteDish,
faClipboard,
faCopy,
faClone,
faAnglesRight,
Expand All @@ -64,18 +75,24 @@ library.add(
faAngleDoubleRight,
faRightFromBracket,
faRightToBracket,
faSquareCaretDown,
faRotateRight,
faHistory,
faSearch,
faUpRightFromSquare,
faIdBadge,
faUserTag,
faTags,
faFileLines,
faKey,
faLayerGroup,
faProjectDiagram,
faNetworkWired,
faHdd,
faUsers,
faUbuntu,
faLinux,
faDebian,
faWindows,
faServer,
faDatabase,
Expand Down
4 changes: 4 additions & 0 deletions app/models/actor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ def downcased_name
name.downcase
end

def initials
name.split(' ').map(&:first).map(&:upcase).join
end

def numbering
return unless prefs['numbered']
count = prefs.dig('numbered', 'count').presence || 0
Expand Down
1 change: 1 addition & 0 deletions app/models/address.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class Address < ApplicationRecord
belongs_to :address_pool, touch: true, optional: true
has_one :virtual_machine, through: :network_interface
has_one :network, through: :network_interface
has_one :actor, through: :network

delegate :exercise, to: :network

Expand Down
4 changes: 4 additions & 0 deletions app/models/operating_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,14 @@ def applied_primary_disk_size

def to_icon
case slug
when /debian/
'fa-brands fa-debian'
when /ubuntu/
'fa-brands fa-ubuntu'
when /win/
'fa-brands fa-windows'
when /linux/
'fa-brands fa-linux'
else
'fa-solid fa-server'
end
Expand Down
19 changes: 12 additions & 7 deletions app/models/virtual_machine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,24 @@ class VirtualMachine < ApplicationRecord
belongs_to :numbered_by, polymorphic: true, optional: true
has_many :network_interfaces, dependent: :destroy
has_many :customization_specs, dependent: :destroy
has_one :connection_nic, -> { connectable },
class_name: 'NetworkInterface', foreign_key: :virtual_machine_id
has_one :host_spec, -> { mode_host },
class_name: 'CustomizationSpec', foreign_key: :virtual_machine_id

has_many :networks, through: :network_interfaces
has_many :addresses, through: :network_interfaces
has_and_belongs_to_many :services,
after_add: :invalidate_cache, after_remove: :invalidate_cache
has_and_belongs_to_many :capabilities,
after_add: :invalidate_cache, after_remove: :invalidate_cache

has_one :connection_nic, -> { connectable },
class_name: 'NetworkInterface', foreign_key: :virtual_machine_id
has_one :host_spec, -> { mode_host },
class_name: 'CustomizationSpec', foreign_key: :virtual_machine_id

accepts_nested_attributes_for :network_interfaces,
reject_if: proc { |attributes| attributes.all? { |key, value| value.blank? || value == '0' } }

scope :search, ->(query) {
columns = %w{virtual_machines.name customization_specs.dns_name users.name operating_systems.name}
left_outer_joins(:system_owner, :operating_system, :customization_specs)
columns = %w{virtual_machines.name customization_specs.dns_name users.name operating_systems.name tags.name}
left_outer_joins(:system_owner, :operating_system, customization_specs: { taggings: [:tag] })
.where(
columns
.map { |c| "lower(#{c}) ilike :search" }
Expand Down Expand Up @@ -97,6 +97,11 @@ def clustered?
custom_instance_count.to_i > 0
end

def connection_address
return unless connection_nic
connection_nic.addresses.detect(&:connection?)
end

private
def lowercase_fields
name.downcase! if name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
= form.collection_select :matcher, actor_number_config.actor.all_numbers, :to_s, :to_s, { include_blank: true }, { class: 'form-input mt-1', multiple: true, data: { controller: 'select'} }

.pt-9
= link_to 'javascript:;', class: 'text-white bg-gradient-to-r from-cyan-400 via-cyan-500 to-cyan-600 hover:bg-gradient-to-br focus:ring-4 focus:outline-none focus:ring-cyan-300 dark:focus:ring-cyan-800 font-medium rounded-lg text-sm text-center px-5 py-2.5', data: { action: "click->modal#open" } do
= link_to 'javascript:;', class: 'text-white bg-gradient-to-r from-purple-500 to-pink-500 hover:bg-gradient-to-l focus:ring-4 focus:outline-none focus:ring-purple-200 dark:focus:ring-purple-800 font-medium rounded-lg text-sm text-center px-5 py-2.5', data: { action: "click->modal#open" } do
Config map
%i.fas.fa-up-right-from-square

Expand Down
4 changes: 2 additions & 2 deletions app/views/addresses/_address.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
.text-center.text-gray-500 Automatic configuration
- if address.connection?
.shrink-0.self-center.inline-flex.items-center.justify-center.rounded-full.bg-orange-200.text-orange-800.w-7.h-7{title: Address.human_attribute_name(:connection)}
%i.fas.fa-cogs.text-sm
%i.fas.fa-satellite-dish.text-sm

.relative.inline-flex{"data-controller" => "dropdown"}
.inline-flex.justify-center.items-center.group.select-none{"data-action" => "click->dropdown#toggle click@window->dropdown#hide", "data-dropdown-target" => "button", :role => "button", :tabindex => "0"}
Expand Down Expand Up @@ -61,7 +61,7 @@

- if address.connection? && address.fixed?
.self-center.inline-flex.items-center.justify-center.rounded-full.bg-orange-200.text-orange-800.w-7.h-7{title: Address.human_attribute_name(:connection)}
%i.fas.fa-cogs.text-sm
%i.fas.fa-satellite-dish.text-sm

- if address.needs_pool? && address.offset
.self-center.flex.items-center.justify-center.rounded-full.bg-blue-200.text-blue-800.w-7.h-7{class: !address.dns_enabled ? 'opacity-70' : ''}
Expand Down
Loading
Loading