Compare commits
No commits in common. "main" and "ruby" have entirely different histories.
3
.gitignore
vendored
3
.gitignore
vendored
@ -59,9 +59,6 @@ build-iPhoneSimulator/
|
|||||||
# Local database storage
|
# Local database storage
|
||||||
data/raven.db
|
data/raven.db
|
||||||
|
|
||||||
# Local configuration
|
|
||||||
config/raven.yaml
|
|
||||||
|
|
||||||
# Node modules for Grunt.js
|
# Node modules for Grunt.js
|
||||||
node_modules/
|
node_modules/
|
||||||
|
|
||||||
|
4
Gemfile
4
Gemfile
@ -1,13 +1,11 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
gem 'sinatra', '~> 3.0'
|
gem 'sinatra', '~> 3.0'
|
||||||
gem 'sinatra-contrib', '~> 3.0'
|
|
||||||
gem 'puma', '~> 6.0'
|
gem 'puma', '~> 6.0'
|
||||||
|
|
||||||
gem 'sequel', '~> 5.63'
|
gem 'sequel', '~> 5.63'
|
||||||
gem 'sqlite3', '~> 1.5'
|
gem 'sqlite3', '~> 1.5'
|
||||||
|
|
||||||
# Use rerun gem to auto-reload app
|
# Use rerun gem to auto-reload app
|
||||||
gem 'guard-rack'
|
gem 'rerun'
|
||||||
gem 'wdm', '>= 0.1.0' if Gem.win_platform?
|
|
||||||
|
|
||||||
|
42
Gemfile.lock
42
Gemfile.lock
@ -1,39 +1,14 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
coderay (1.1.3)
|
|
||||||
ffi (1.15.5)
|
ffi (1.15.5)
|
||||||
ffi (1.15.5-x64-mingw-ucrt)
|
ffi (1.15.5-x64-mingw-ucrt)
|
||||||
formatador (1.1.0)
|
listen (3.7.1)
|
||||||
guard (2.18.0)
|
|
||||||
formatador (>= 0.2.4)
|
|
||||||
listen (>= 2.7, < 4.0)
|
|
||||||
lumberjack (>= 1.0.12, < 2.0)
|
|
||||||
nenv (~> 0.1)
|
|
||||||
notiffany (~> 0.0)
|
|
||||||
pry (>= 0.13.0)
|
|
||||||
shellany (~> 0.0)
|
|
||||||
thor (>= 0.18.1)
|
|
||||||
guard-rack (2.2.1)
|
|
||||||
ffi
|
|
||||||
guard (~> 2.3)
|
|
||||||
spoon
|
|
||||||
listen (3.8.0)
|
|
||||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
rb-inotify (~> 0.9, >= 0.9.10)
|
rb-inotify (~> 0.9, >= 0.9.10)
|
||||||
lumberjack (1.2.8)
|
|
||||||
method_source (1.0.0)
|
|
||||||
multi_json (1.15.0)
|
|
||||||
mustermann (3.0.0)
|
mustermann (3.0.0)
|
||||||
ruby2_keywords (~> 0.0.1)
|
ruby2_keywords (~> 0.0.1)
|
||||||
nenv (0.3.0)
|
|
||||||
nio4r (2.5.8)
|
nio4r (2.5.8)
|
||||||
notiffany (0.1.3)
|
|
||||||
nenv (~> 0.1)
|
|
||||||
shellany (~> 0.0)
|
|
||||||
pry (0.14.2)
|
|
||||||
coderay (~> 1.1)
|
|
||||||
method_source (~> 1.0)
|
|
||||||
puma (6.0.0)
|
puma (6.0.0)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
rack (2.2.4)
|
rack (2.2.4)
|
||||||
@ -42,25 +17,17 @@ GEM
|
|||||||
rb-fsevent (0.11.2)
|
rb-fsevent (0.11.2)
|
||||||
rb-inotify (0.10.1)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
|
rerun (0.13.1)
|
||||||
|
listen (~> 3.0)
|
||||||
ruby2_keywords (0.0.5)
|
ruby2_keywords (0.0.5)
|
||||||
sequel (5.63.0)
|
sequel (5.63.0)
|
||||||
shellany (0.0.1)
|
|
||||||
sinatra (3.0.4)
|
sinatra (3.0.4)
|
||||||
mustermann (~> 3.0)
|
mustermann (~> 3.0)
|
||||||
rack (~> 2.2, >= 2.2.4)
|
rack (~> 2.2, >= 2.2.4)
|
||||||
rack-protection (= 3.0.4)
|
rack-protection (= 3.0.4)
|
||||||
tilt (~> 2.0)
|
tilt (~> 2.0)
|
||||||
sinatra-contrib (3.0.4)
|
|
||||||
multi_json
|
|
||||||
mustermann (~> 3.0)
|
|
||||||
rack-protection (= 3.0.4)
|
|
||||||
sinatra (= 3.0.4)
|
|
||||||
tilt (~> 2.0)
|
|
||||||
spoon (0.0.6)
|
|
||||||
ffi
|
|
||||||
sqlite3 (1.5.4-x64-mingw-ucrt)
|
sqlite3 (1.5.4-x64-mingw-ucrt)
|
||||||
sqlite3 (1.5.4-x86_64-linux)
|
sqlite3 (1.5.4-x86_64-linux)
|
||||||
thor (1.2.1)
|
|
||||||
tilt (2.0.11)
|
tilt (2.0.11)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
@ -68,11 +35,10 @@ PLATFORMS
|
|||||||
x86_64-linux
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
guard-rack
|
|
||||||
puma (~> 6.0)
|
puma (~> 6.0)
|
||||||
|
rerun
|
||||||
sequel (~> 5.63)
|
sequel (~> 5.63)
|
||||||
sinatra (~> 3.0)
|
sinatra (~> 3.0)
|
||||||
sinatra-contrib (~> 3.0)
|
|
||||||
sqlite3 (~> 1.5)
|
sqlite3 (~> 1.5)
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
|
30
Gruntfile.js
30
Gruntfile.js
@ -19,21 +19,6 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
coffee: {
|
|
||||||
options: {
|
|
||||||
sourceMap: true,
|
|
||||||
style: 'compressed'
|
|
||||||
},
|
|
||||||
files: {
|
|
||||||
expand: true,
|
|
||||||
flatten: true,
|
|
||||||
cwd: 'assets/coffee',
|
|
||||||
src: ['*.coffee'],
|
|
||||||
dest: 'public/js',
|
|
||||||
ext: '.js'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
css: {
|
css: {
|
||||||
files: ['assets/styles/**/*.scss'],
|
files: ['assets/styles/**/*.scss'],
|
||||||
@ -42,24 +27,15 @@ module.exports = function(grunt) {
|
|||||||
atBegin: true,
|
atBegin: true,
|
||||||
spawn: false
|
spawn: false
|
||||||
}
|
}
|
||||||
},
|
|
||||||
js: {
|
|
||||||
files: ['assets/coffee/*.coffee'],
|
|
||||||
tasks: ['coffee'],
|
|
||||||
options: {
|
|
||||||
atBegin: true,
|
|
||||||
spawn: false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Load plugins.
|
// Load plugins.
|
||||||
grunt.loadNpmTasks('grunt-contrib-sass');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-coffee');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-sass');
|
||||||
|
|
||||||
// Default task(s).
|
// CLI tasks.
|
||||||
grunt.registerTask('default', ['sass', 'coffee']);
|
grunt.registerTask('default', ['sass']);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
guard 'rack' do
|
|
||||||
watch('Gemfile.lock')
|
|
||||||
watch('config.ru')
|
|
||||||
watch('server.rb')
|
|
||||||
watch(%r{^(lib)/.*})
|
|
||||||
end
|
|
20
Rakefile
20
Rakefile
@ -1,20 +0,0 @@
|
|||||||
require 'bundler/setup'
|
|
||||||
|
|
||||||
require 'sequel'
|
|
||||||
require 'sqlite3'
|
|
||||||
|
|
||||||
namespace :db do
|
|
||||||
task :migrate do
|
|
||||||
%x{sequel -m 'db/migrations/' 'sqlite://data/raven.db'}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
namespace :server do
|
|
||||||
task :start do
|
|
||||||
system("puma -C config/puma.rb")
|
|
||||||
end
|
|
||||||
|
|
||||||
task :dev do
|
|
||||||
%x{guard}
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,21 +0,0 @@
|
|||||||
module Helpers
|
|
||||||
|
|
||||||
def nullable(value)
|
|
||||||
if (value) and (value != '')
|
|
||||||
return value
|
|
||||||
else
|
|
||||||
return 'N/a'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def date_format(date)
|
|
||||||
dt = date.to_datetime
|
|
||||||
return dt.strftime('%B %d, %Y @ %I:%M:%S %p %Z')
|
|
||||||
end
|
|
||||||
|
|
||||||
def date_format_input(date)
|
|
||||||
dt = date.to_datetime
|
|
||||||
return dt.strftime('%Y-%m-%dT%H:%M:%S')
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,5 +0,0 @@
|
|||||||
class IpAddress < Sequel::Model
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
@ -1,17 +0,0 @@
|
|||||||
class Item < Sequel::Model
|
|
||||||
|
|
||||||
one_to_many :item_comments
|
|
||||||
|
|
||||||
def getLink()
|
|
||||||
return "/item/#{self.id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def type_selected?(option)
|
|
||||||
if self.type == option
|
|
||||||
return 'selected'
|
|
||||||
else
|
|
||||||
return ''
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,5 +0,0 @@
|
|||||||
class ItemComment < Sequel::Model
|
|
||||||
|
|
||||||
many_to_one :items
|
|
||||||
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
class License < Sequel::Model
|
|
||||||
|
|
||||||
one_to_many :license_comments
|
|
||||||
|
|
||||||
def getLink()
|
|
||||||
return "/license/#{self.id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,5 +0,0 @@
|
|||||||
class LicenseComment < Sequel::Model
|
|
||||||
|
|
||||||
many_to_one :licenses
|
|
||||||
|
|
||||||
end
|
|
@ -1,9 +0,0 @@
|
|||||||
require_relative 'routes/index.rb'
|
|
||||||
|
|
||||||
require_relative 'routes/item.rb'
|
|
||||||
|
|
||||||
require_relative 'routes/license.rb'
|
|
||||||
|
|
||||||
require_relative 'routes/search.rb'
|
|
||||||
|
|
||||||
require_relative 'routes/ip_tracker.rb'
|
|
@ -1,16 +0,0 @@
|
|||||||
class Raven
|
|
||||||
class IndexController
|
|
||||||
|
|
||||||
get '/' do
|
|
||||||
items = Item.reverse(:updated_at).limit(10).all()
|
|
||||||
licenses = License.reverse(:updated_at).limit(10).all()
|
|
||||||
erb :index, :locals => {
|
|
||||||
:title => 'Dashboard',
|
|
||||||
:items => items,
|
|
||||||
:licenses => licenses
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
|||||||
require 'ipaddr'
|
|
||||||
|
|
||||||
class Raven
|
|
||||||
class IpTrackerController
|
|
||||||
|
|
||||||
get '/' do
|
|
||||||
ip_addresses = IpAddress.all()
|
|
||||||
ip_addresses.sort! { |a,b| IPAddr.new( a.address ) <=> IPAddr.new( b.address ) }
|
|
||||||
|
|
||||||
erb :'ip/ip-tracker', :locals => {
|
|
||||||
:title => 'IP Tracker',
|
|
||||||
:ip_addresses => ip_addresses
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/add' do
|
|
||||||
erb :'ip/add', :locals => {
|
|
||||||
:title => 'Add IP Address'
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
post '/add' do
|
|
||||||
ip = IpAddress.create(
|
|
||||||
address: params[:ip_address],
|
|
||||||
dns_name: params[:ip_dns],
|
|
||||||
comment: params[:ip_comment]
|
|
||||||
)
|
|
||||||
|
|
||||||
redirect '/ip-tracker'
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/delete/:ip_id' do
|
|
||||||
ip = IpAddress.where(id: params[:ip_id]).first()
|
|
||||||
ip.delete()
|
|
||||||
|
|
||||||
redirect '/ip-tracker'
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,83 +0,0 @@
|
|||||||
class Raven
|
|
||||||
class ItemController
|
|
||||||
|
|
||||||
get '/' do
|
|
||||||
redirect '/item/list'
|
|
||||||
end
|
|
||||||
get '/list' do
|
|
||||||
items = Item.reverse(:updated_at).all()
|
|
||||||
erb :'item/list', :locals => {
|
|
||||||
:title => 'List of Items',
|
|
||||||
:items => items
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/create' do
|
|
||||||
erb :'item/create', :locals => {
|
|
||||||
:title => 'Create New Item'
|
|
||||||
}
|
|
||||||
end
|
|
||||||
post '/create' do
|
|
||||||
item = Item.create(
|
|
||||||
name: params[:item_name],
|
|
||||||
serial_number: params[:item_serial],
|
|
||||||
sku_number: params[:item_sku],
|
|
||||||
purchased_from: params[:item_purchase_from],
|
|
||||||
purchased_at: params[:item_purchase_date],
|
|
||||||
manufacturer: params[:item_manufacturer],
|
|
||||||
type: params[:item_type]
|
|
||||||
)
|
|
||||||
|
|
||||||
redirect "/item/#{item.id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/:item_id' do
|
|
||||||
item = Item.where(id: params[:item_id]).first()
|
|
||||||
puts "#{item.name}"
|
|
||||||
erb :'item/view', :locals => {
|
|
||||||
:title => item.name,
|
|
||||||
:item => item
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/:item_id/edit' do
|
|
||||||
item = Item.where(id: params[:item_id]).first()
|
|
||||||
puts "#{item.name}"
|
|
||||||
erb :'item/edit', :locals => {
|
|
||||||
:title => "Editing: #{item.name}",
|
|
||||||
:item => item
|
|
||||||
}
|
|
||||||
end
|
|
||||||
post '/:item_id/edit' do
|
|
||||||
item = Item.where(id: params[:item_id]).first()
|
|
||||||
|
|
||||||
item.name = params[:item_name]
|
|
||||||
item.serial_number = params[:item_serial]
|
|
||||||
item.sku_number = params[:item_sku]
|
|
||||||
item.purchased_from = params[:item_purchase_from]
|
|
||||||
item.purchased_at = params[:item_purchase_date]
|
|
||||||
item.manufacturer = params[:item_manufacturer]
|
|
||||||
item.type = params[:item_type]
|
|
||||||
item.save()
|
|
||||||
|
|
||||||
redirect "/item/#{item.id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/:item_id/delete' do
|
|
||||||
item = Item.where(id: params[:item_id]).first()
|
|
||||||
item.delete()
|
|
||||||
|
|
||||||
redirect '/item/list'
|
|
||||||
end
|
|
||||||
|
|
||||||
post '/:item_id/comment' do
|
|
||||||
item = Item.first(id: params[:item_id])
|
|
||||||
|
|
||||||
comment = ItemComment.create(body: params[:comment_body])
|
|
||||||
item.add_item_comment(comment)
|
|
||||||
|
|
||||||
redirect "/item/#{item.id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,83 +0,0 @@
|
|||||||
class Raven
|
|
||||||
class LicenseController
|
|
||||||
|
|
||||||
get '/' do
|
|
||||||
redirect '/license/list'
|
|
||||||
end
|
|
||||||
get '/list' do
|
|
||||||
licenses = License.reverse(:updated_at).all()
|
|
||||||
erb :'license/list', :locals => {
|
|
||||||
:title => 'List of Licenses',
|
|
||||||
:licenses => licenses
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/create' do
|
|
||||||
erb :'license/create', :locals => {
|
|
||||||
:title => 'Create New License'
|
|
||||||
}
|
|
||||||
end
|
|
||||||
post '/create' do
|
|
||||||
license = License.create(
|
|
||||||
name: params[:license_name],
|
|
||||||
key: params[:license_key],
|
|
||||||
manufacturer: params[:license_manufacturer],
|
|
||||||
seats_used: params[:license_seats_used],
|
|
||||||
seats_total: params[:license_seats_total],
|
|
||||||
purchased_from: params[:license_purchase_from],
|
|
||||||
purchased_at: params[:license_purchase_date]
|
|
||||||
)
|
|
||||||
|
|
||||||
redirect "/license/#{license.id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/:license_id' do
|
|
||||||
license = License.where(id: params[:license_id]).first()
|
|
||||||
puts "#{license.name}"
|
|
||||||
erb :'license/view', :locals => {
|
|
||||||
:title => license.name,
|
|
||||||
:license => license
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/:license_id/edit' do
|
|
||||||
license = License.where(id: params[:license_id]).first()
|
|
||||||
puts "#{license.name}"
|
|
||||||
erb :'license/edit', :locals => {
|
|
||||||
:title => "Editing: #{license.name}",
|
|
||||||
:license => license
|
|
||||||
}
|
|
||||||
end
|
|
||||||
post '/:license_id/edit' do
|
|
||||||
license = License.where(id: params[:license_id]).first()
|
|
||||||
|
|
||||||
license.name = params[:license_name]
|
|
||||||
license.key = params[:license_key]
|
|
||||||
license.manufacturer = params[:license_manufacturer]
|
|
||||||
license.seats_used = params[:license_seats_used]
|
|
||||||
license.seats_total = params[:license_seats_total]
|
|
||||||
license.purchased_from = params[:license_purchase_from]
|
|
||||||
license.purchased_at = params[:license_purchase_date]
|
|
||||||
license.save()
|
|
||||||
|
|
||||||
redirect "/license/#{license.id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
get '/:license_id/delete' do
|
|
||||||
license = License.where(id: params[:license_id]).first()
|
|
||||||
license.delete()
|
|
||||||
|
|
||||||
redirect '/license/list'
|
|
||||||
end
|
|
||||||
|
|
||||||
post '/:license_id/comment' do
|
|
||||||
license = License.first(id: params[:license_id])
|
|
||||||
|
|
||||||
comment = LicenseComment.create(body: params[:comment_body])
|
|
||||||
license.add_license_comment(comment)
|
|
||||||
|
|
||||||
redirect "/license/#{license.id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,19 +0,0 @@
|
|||||||
class Raven
|
|
||||||
class SearchController
|
|
||||||
|
|
||||||
get '/' do
|
|
||||||
search_parameter = params[:query]
|
|
||||||
items = Item.where(Sequel.ilike(:name, "%#{search_parameter}%")).all()
|
|
||||||
licenses = License.where(Sequel.ilike(:name, "%#{search_parameter}%")).all()
|
|
||||||
|
|
||||||
results = items.concat(licenses)
|
|
||||||
|
|
||||||
erb :'search/list', :locals => {
|
|
||||||
:title => 'Search Results',
|
|
||||||
:results => results,
|
|
||||||
:query => search_parameter
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,43 +0,0 @@
|
|||||||
$(document).ready( ->
|
|
||||||
|
|
||||||
$('#nav-toggle').on('click', toggleNav)
|
|
||||||
if getCookie('navCollapsed') == 'true'
|
|
||||||
$('body').addClass('collapsed')
|
|
||||||
$('#mobile-nav-toggle').on('click', toggleMobileNav)
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
toggleNav = () ->
|
|
||||||
bodyElem = $('body')
|
|
||||||
if bodyElem.hasClass('collapsed')
|
|
||||||
bodyElem.removeClass('collapsed')
|
|
||||||
setCookie('navCollapsed', 'false')
|
|
||||||
else
|
|
||||||
bodyElem.addClass('collapsed')
|
|
||||||
setCookie('navCollapsed', 'true')
|
|
||||||
|
|
||||||
toggleMobileNav = () ->
|
|
||||||
navElem = $('#mobile-nav')
|
|
||||||
if navElem.hasClass('expanded')
|
|
||||||
navElem.removeClass('expanded')
|
|
||||||
else
|
|
||||||
navElem.addClass('expanded')
|
|
||||||
|
|
||||||
getCookie = (cName) ->
|
|
||||||
name = cName + '='
|
|
||||||
cDecoded = decodeURIComponent(document.cookie)
|
|
||||||
#to be careful
|
|
||||||
cArr = cDecoded.split('; ')
|
|
||||||
res = undefined
|
|
||||||
cArr.forEach (val) ->
|
|
||||||
if val.indexOf(name) == 0
|
|
||||||
res = val.substring(name.length)
|
|
||||||
return
|
|
||||||
res
|
|
||||||
|
|
||||||
setCookie = (cName, cValue, expDays = 30) ->
|
|
||||||
date = new Date
|
|
||||||
date.setTime date.getTime() + expDays * 24 * 60 * 60 * 1000
|
|
||||||
expires = 'expires=' + date.toUTCString()
|
|
||||||
document.cookie = cName + '=' + cValue + '; ' + expires + '; path=/'
|
|
||||||
return
|
|
@ -5,96 +5,6 @@ $box-shadow-2: 0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23);
|
|||||||
|
|
||||||
body{
|
body{
|
||||||
background: lightgrey;
|
background: lightgrey;
|
||||||
padding-left: $nav-width;
|
|
||||||
transition: padding-left 230ms ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card{
|
|
||||||
padding: 20px 30px;
|
|
||||||
background: white;
|
|
||||||
border-radius: 5px;
|
|
||||||
box-shadow: $box-shadow-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 992px) {
|
|
||||||
body,
|
|
||||||
body.collapsed{
|
|
||||||
padding-left: 0 !important;
|
|
||||||
}
|
|
||||||
#main-nav{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#mobile-nav{
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (min-width: 993px) {
|
|
||||||
#mobile-nav{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#mobile-nav{
|
|
||||||
width: calc(100% + 16px);
|
|
||||||
height: 55px;
|
|
||||||
margin-top: -8px;
|
|
||||||
margin-left: -8px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
background: #212121;
|
|
||||||
color: white;
|
|
||||||
font-size: 3rem;
|
|
||||||
box-shadow: $box-shadow-1;
|
|
||||||
overflow-y: hidden;
|
|
||||||
transition: height 230ms ease-in-out;
|
|
||||||
|
|
||||||
span{
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
padding-top: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul{
|
|
||||||
list-style: none;
|
|
||||||
|
|
||||||
li{
|
|
||||||
margin: 0;
|
|
||||||
border-bottom: 1px solid #999;
|
|
||||||
|
|
||||||
&:first-child{
|
|
||||||
border-top: 1px solid #999;
|
|
||||||
}
|
|
||||||
|
|
||||||
i{
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 18px;
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 3rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a{
|
|
||||||
display: block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px 15px;
|
|
||||||
color: limegreen;
|
|
||||||
font-size: 2.5rem;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: all 230ms ease-in-out;
|
|
||||||
|
|
||||||
&:hover{
|
|
||||||
background: rgba(255, 255, 255, 0.1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#mobile-nav.expanded{
|
|
||||||
height: 300px;
|
|
||||||
i{
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#main-nav{
|
#main-nav{
|
||||||
@ -108,21 +18,9 @@ body{
|
|||||||
color: white;
|
color: white;
|
||||||
box-shadow: $box-shadow-1;
|
box-shadow: $box-shadow-1;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
transition: left 230ms ease-in-out;
|
|
||||||
|
|
||||||
h3{
|
h3{
|
||||||
padding-left: 15px;
|
text-align: center;
|
||||||
text-align: left;
|
|
||||||
|
|
||||||
i{
|
|
||||||
position: absolute;
|
|
||||||
right: 22px;
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 3rem;
|
|
||||||
&:hover{
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ul{
|
ul{
|
||||||
@ -135,13 +33,6 @@ body{
|
|||||||
&:first-child{
|
&:first-child{
|
||||||
border-top: 1px solid #999;
|
border-top: 1px solid #999;
|
||||||
}
|
}
|
||||||
|
|
||||||
i{
|
|
||||||
position: absolute;
|
|
||||||
right: 18px;
|
|
||||||
margin-top: 5px;
|
|
||||||
font-size: 3rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
a{
|
a{
|
||||||
@ -161,57 +52,11 @@ body{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body.collapsed{
|
|
||||||
padding-left: 64px;
|
|
||||||
}
|
|
||||||
body.collapsed #main-nav{
|
|
||||||
left: calc($nav-width * -1 + 64px);
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-actions{
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 25px;
|
|
||||||
|
|
||||||
form,
|
|
||||||
input{
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#main-wrapper{
|
#main-wrapper{
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin-top: 25px;
|
margin-top: 25px;
|
||||||
}
|
padding: 20px 30px;
|
||||||
|
background: white;
|
||||||
#main-wrapper.container.fluid{
|
border-radius: 5px;
|
||||||
width: 100%;
|
box-shadow: $box-shadow-2;
|
||||||
max-width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#site-header{
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#item-header,
|
|
||||||
#license-header{
|
|
||||||
.item-name,
|
|
||||||
.license-name{
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item-created,
|
|
||||||
.item-updated,
|
|
||||||
.license-created,
|
|
||||||
.license-updated{
|
|
||||||
color: #666;
|
|
||||||
font-size: 1.75rem;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.u-text-centered{
|
|
||||||
text-align: center;
|
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
# Load application config
|
|
||||||
require_relative 'app/config.rb'
|
|
||||||
$conf = Config.new(File.join(__dir__, 'data/defaults.yaml'))
|
|
||||||
|
|
||||||
# Load Sinatra server
|
|
||||||
require_relative './server.rb'
|
|
||||||
|
|
||||||
# Run application
|
|
||||||
run Raven
|
|
@ -1,6 +0,0 @@
|
|||||||
# Load application config
|
|
||||||
require './app/config.rb'
|
|
||||||
$conf = Config.new(File.join(__dir__, 'config/raven.yaml'))
|
|
||||||
|
|
||||||
bind_address = "tcp://#{$conf.get('server.address')}:#{$conf.get('server.port')}"
|
|
||||||
bind bind_address
|
|
@ -1,7 +1,3 @@
|
|||||||
server:
|
|
||||||
address: '127.0.0.1'
|
|
||||||
port: 6200
|
|
||||||
|
|
||||||
database:
|
database:
|
||||||
adapter: 'sqlite'
|
adapter: 'sqlite'
|
||||||
database: 'data/raven.db'
|
database: 'data/raven.db'
|
@ -10,8 +10,8 @@ Sequel.migration do
|
|||||||
String :type
|
String :type
|
||||||
String :purchased_from
|
String :purchased_from
|
||||||
DateTime :purchased_at
|
DateTime :purchased_at
|
||||||
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
DateTime :created_at
|
||||||
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
DateTime :updated_at
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,20 +0,0 @@
|
|||||||
Sequel.migration do
|
|
||||||
|
|
||||||
up do
|
|
||||||
create_table(:item_comments) do
|
|
||||||
primary_key :id
|
|
||||||
String :body, null: false
|
|
||||||
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
|
||||||
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
|
||||||
end
|
|
||||||
|
|
||||||
alter_table(:item_comments) do
|
|
||||||
add_foreign_key :item_id, :items
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
down do
|
|
||||||
drop_table(:item_comments)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,22 +0,0 @@
|
|||||||
Sequel.migration do
|
|
||||||
|
|
||||||
up do
|
|
||||||
create_table(:licenses) do
|
|
||||||
primary_key :id
|
|
||||||
String :name, null: false
|
|
||||||
String :key, null: false
|
|
||||||
String :manufacturer
|
|
||||||
Integer :seats_used, default: 0
|
|
||||||
Integer :seats_total, default: 1
|
|
||||||
String :purchased_from
|
|
||||||
DateTime :purchased_at
|
|
||||||
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
|
||||||
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
down do
|
|
||||||
drop_table(:licenses)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,20 +0,0 @@
|
|||||||
Sequel.migration do
|
|
||||||
|
|
||||||
up do
|
|
||||||
create_table(:license_comments) do
|
|
||||||
primary_key :id
|
|
||||||
String :body, null: false
|
|
||||||
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
|
||||||
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
|
||||||
end
|
|
||||||
|
|
||||||
alter_table(:license_comments) do
|
|
||||||
add_foreign_key :license_id, :licenses
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
down do
|
|
||||||
drop_table(:license_comments)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -1,18 +0,0 @@
|
|||||||
Sequel.migration do
|
|
||||||
|
|
||||||
up do
|
|
||||||
create_table(:ip_addresses) do
|
|
||||||
primary_key :id
|
|
||||||
String :address, null: false
|
|
||||||
String :dns_name
|
|
||||||
String :comment
|
|
||||||
DateTime :created_at, default: Sequel::CURRENT_TIMESTAMP
|
|
||||||
DateTime :updated_at, default: Sequel::CURRENT_TIMESTAMP
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
down do
|
|
||||||
drop_table(:ip_addresses)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
@ -2,14 +2,8 @@ require 'yaml'
|
|||||||
|
|
||||||
class Config
|
class Config
|
||||||
|
|
||||||
DEFAULT_CONFIG = 'config/defaults.yaml'
|
|
||||||
|
|
||||||
def initialize(config_path)
|
def initialize(config_path)
|
||||||
@data = YAML::load_file(DEFAULT_CONFIG)
|
@data = YAML::load_file(config_path)
|
||||||
|
|
||||||
if File.exists?(config_path)
|
|
||||||
@data.merge!(YAML::load_file(config_path))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def get(key, depth = 0)
|
def get(key, depth = 0)
|
5
lib/models/item.rb
Normal file
5
lib/models/item.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
class Item < Sequel::Model
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end
|
37
lib/routes.rb
Normal file
37
lib/routes.rb
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
get '/' do
|
||||||
|
items = Item.all
|
||||||
|
erb :index, :locals => {
|
||||||
|
:title => 'Dashboard',
|
||||||
|
:items => items
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/item' do
|
||||||
|
redirect '/item/list'
|
||||||
|
end
|
||||||
|
get '/item/list' do
|
||||||
|
items = Item.all
|
||||||
|
erb :'item/list', :locals => {
|
||||||
|
:title => 'List of Items',
|
||||||
|
:items => items
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
get '/item/create' do
|
||||||
|
erb :'item/create', :locals => {
|
||||||
|
:title => 'Create New Item'
|
||||||
|
}
|
||||||
|
end
|
||||||
|
post '/item/create' do
|
||||||
|
item = Item.create(
|
||||||
|
name: params[:item_name],
|
||||||
|
serial_number: params[:item_serial],
|
||||||
|
sku_number: params[:item_sku],
|
||||||
|
purchased_from: params[:item_purchase_from],
|
||||||
|
purchased_at: params[:item_purchase_date],
|
||||||
|
manufacturer: params[:item_manufacturer],
|
||||||
|
type: params[:item_type]
|
||||||
|
)
|
||||||
|
|
||||||
|
redirect "/item/#{item.id}"
|
||||||
|
end
|
65
package-lock.json
generated
65
package-lock.json
generated
@ -11,7 +11,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "^1.5.3",
|
"grunt": "^1.5.3",
|
||||||
"grunt-cli": "^1.4.3",
|
"grunt-cli": "^1.4.3",
|
||||||
"grunt-contrib-coffee": "^2.1.0",
|
|
||||||
"grunt-contrib-sass": "^2.0.0",
|
"grunt-contrib-sass": "^2.0.0",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"sass": "^1.55.0"
|
"sass": "^1.55.0"
|
||||||
@ -193,19 +192,6 @@
|
|||||||
"fsevents": "~2.3.2"
|
"fsevents": "~2.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/coffeescript": {
|
|
||||||
"version": "2.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.7.0.tgz",
|
|
||||||
"integrity": "sha512-hzWp6TUE2d/jCcN67LrW1eh5b/rSDKQK6oD6VMLlggYVUUFexgTH9z3dNYihzX4RMhze5FTUsUmOXViJKFQR/A==",
|
|
||||||
"dev": true,
|
|
||||||
"bin": {
|
|
||||||
"cake": "bin/cake",
|
|
||||||
"coffee": "bin/coffee"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=6"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/color-convert": {
|
"node_modules/color-convert": {
|
||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
@ -654,24 +640,6 @@
|
|||||||
"nopt": "bin/nopt.js"
|
"nopt": "bin/nopt.js"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/grunt-contrib-coffee": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-lgP+pPY3mHl+gqAU0T+7BcocBWu0FyeeJnAG/iIp2I0GPa5LvZJ7Wqga6QwKQtQCTs+1gPEa12nuap9Lj08lhw==",
|
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
|
||||||
"chalk": "^2.4.2",
|
|
||||||
"coffeescript": "^2.3.2",
|
|
||||||
"lodash": "^4.17.11",
|
|
||||||
"uri-path": "^1.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"grunt": ">=0.4.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/grunt-contrib-sass": {
|
"node_modules/grunt-contrib-sass": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/grunt-contrib-sass/-/grunt-contrib-sass-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/grunt-contrib-sass/-/grunt-contrib-sass-2.0.0.tgz",
|
||||||
@ -1711,15 +1679,6 @@
|
|||||||
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
|
"integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/uri-path": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-8pMuAn4KacYdGMkFaoQARicp4HSw24/DHOVKWqVRJ8LhhAwPPFpdGvdL9184JVmUwe7vz7Z9n6IqI6t5n2ELdg==",
|
|
||||||
"dev": true,
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 0.10"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
@ -1922,12 +1881,6 @@
|
|||||||
"readdirp": "~3.6.0"
|
"readdirp": "~3.6.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"coffeescript": {
|
|
||||||
"version": "2.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-2.7.0.tgz",
|
|
||||||
"integrity": "sha512-hzWp6TUE2d/jCcN67LrW1eh5b/rSDKQK6oD6VMLlggYVUUFexgTH9z3dNYihzX4RMhze5FTUsUmOXViJKFQR/A==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"color-convert": {
|
"color-convert": {
|
||||||
"version": "1.9.3",
|
"version": "1.9.3",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||||
@ -2276,18 +2229,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"grunt-contrib-coffee": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/grunt-contrib-coffee/-/grunt-contrib-coffee-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-lgP+pPY3mHl+gqAU0T+7BcocBWu0FyeeJnAG/iIp2I0GPa5LvZJ7Wqga6QwKQtQCTs+1gPEa12nuap9Lj08lhw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"chalk": "^2.4.2",
|
|
||||||
"coffeescript": "^2.3.2",
|
|
||||||
"lodash": "^4.17.11",
|
|
||||||
"uri-path": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"grunt-contrib-sass": {
|
"grunt-contrib-sass": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/grunt-contrib-sass/-/grunt-contrib-sass-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/grunt-contrib-sass/-/grunt-contrib-sass-2.0.0.tgz",
|
||||||
@ -3072,12 +3013,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"uri-path": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz",
|
|
||||||
"integrity": "sha512-8pMuAn4KacYdGMkFaoQARicp4HSw24/DHOVKWqVRJ8LhhAwPPFpdGvdL9184JVmUwe7vz7Z9n6IqI6t5n2ELdg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"util-deprecate": {
|
"util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "^1.5.3",
|
"grunt": "^1.5.3",
|
||||||
"grunt-cli": "^1.4.3",
|
"grunt-cli": "^1.4.3",
|
||||||
"grunt-contrib-coffee": "^2.1.0",
|
|
||||||
"grunt-contrib-sass": "^2.0.0",
|
"grunt-contrib-sass": "^2.0.0",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"sass": "^1.55.0"
|
"sass": "^1.55.0"
|
||||||
|
27
raven.rb
Normal file
27
raven.rb
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
require 'logger'
|
||||||
|
require 'sequel'
|
||||||
|
require 'sqlite3'
|
||||||
|
require 'sinatra'
|
||||||
|
|
||||||
|
require_relative 'lib/config.rb'
|
||||||
|
|
||||||
|
set :public_folder, __dir__ + '/public'
|
||||||
|
|
||||||
|
set :views, settings.root + '/views'
|
||||||
|
|
||||||
|
# Load configuration file
|
||||||
|
conf = Config.new(File.join(__dir__, 'data/defaults.yaml'))
|
||||||
|
|
||||||
|
# Initialize logging
|
||||||
|
logger = Logger.new(STDOUT)
|
||||||
|
logger.level = Logger::INFO
|
||||||
|
|
||||||
|
# Load the Sequel timestamps plugin
|
||||||
|
Sequel::Model.plugin :timestamps
|
||||||
|
# Initialize Sequel gem for database actions
|
||||||
|
DB = Sequel.connect(adapter: conf.get('database.adapter'), database: conf.get('database.database'))
|
||||||
|
# Load models
|
||||||
|
require_relative 'lib/models/item.rb'
|
||||||
|
|
||||||
|
# Register route handlers
|
||||||
|
require_relative 'lib/routes.rb'
|
71
server.rb
71
server.rb
@ -1,71 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'logger'
|
|
||||||
require 'sequel'
|
|
||||||
require 'sqlite3'
|
|
||||||
require 'sinatra/base'
|
|
||||||
require 'rack/protection'
|
|
||||||
|
|
||||||
# Load the Sequel timestamps plugin
|
|
||||||
Sequel::Model.plugin(:timestamps)
|
|
||||||
# Initialize Sequel gem for database actions
|
|
||||||
DB = Sequel.connect(adapter: $conf.get('database.adapter'), database: $conf.get('database.database'))
|
|
||||||
# Load models
|
|
||||||
Dir.glob('./app/models/*.rb').sort().each { |f| require f }
|
|
||||||
|
|
||||||
# Base Sinatra app
|
|
||||||
class Raven < Sinatra::Base
|
|
||||||
@@my_app = {}
|
|
||||||
def self.new(*) self < Raven ? super : Rack::URLMap.new(@@my_app) end
|
|
||||||
def self.map(url) @@my_app[url] = self end
|
|
||||||
|
|
||||||
# Enable and configure sessions
|
|
||||||
enable :sessions
|
|
||||||
|
|
||||||
# Enable rack protection middleware
|
|
||||||
use Rack::Protection
|
|
||||||
|
|
||||||
# Set up static file serving
|
|
||||||
enable :static
|
|
||||||
set :public_folder, File.join(__dir__, '/public')
|
|
||||||
|
|
||||||
# Set up our view engine
|
|
||||||
set :views, File.join(settings.root, '/views')
|
|
||||||
|
|
||||||
# Initialize logging
|
|
||||||
logger = Logger.new($stdout)
|
|
||||||
logger.level = Logger::INFO
|
|
||||||
|
|
||||||
# Load helper functions
|
|
||||||
require_relative 'app/helpers'
|
|
||||||
helpers Helpers
|
|
||||||
|
|
||||||
## Map controllers
|
|
||||||
# Top-level routes controller
|
|
||||||
class IndexController < Raven
|
|
||||||
map '/'
|
|
||||||
end
|
|
||||||
|
|
||||||
# Item routes controller
|
|
||||||
class ItemController < Raven
|
|
||||||
map '/item'
|
|
||||||
end
|
|
||||||
|
|
||||||
# License routes controller
|
|
||||||
class LicenseController < Raven
|
|
||||||
map '/license'
|
|
||||||
end
|
|
||||||
|
|
||||||
# Search routes controller
|
|
||||||
class SearchController < Raven
|
|
||||||
map '/search'
|
|
||||||
end
|
|
||||||
|
|
||||||
# IP tracker routes controller
|
|
||||||
class IpTrackerController < Raven
|
|
||||||
map '/ip-tracker'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Load controllers
|
|
||||||
Dir.glob('./app/routes.rb').sort().each { |f| require f }
|
|
@ -1,57 +1,11 @@
|
|||||||
<div class="row">
|
<p>This is a test.</p>
|
||||||
<div class="twelve columns">
|
|
||||||
<h1 id="site-header">Welcome to Raven</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<hr>
|
<% if items.length > 0 %>
|
||||||
|
<ul>
|
||||||
<div class="row">
|
<% items.each do |item| %>
|
||||||
<div class="six columns">
|
<li><%= item.name %></li>
|
||||||
<h3>Recent inventory updates</h3>
|
<% end %>
|
||||||
<% if items.length > 0 %>
|
</ul>
|
||||||
<table class="u-full-width">
|
<% else %>
|
||||||
<thead>
|
<p>There are no items to display.</p>
|
||||||
<tr>
|
<% end %>
|
||||||
<th>Item name</th>
|
|
||||||
<th>Updated at</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% items.each do |item| %>
|
|
||||||
<tr>
|
|
||||||
<td><%= item.name %></td>
|
|
||||||
<td><%= date_format(item.updated_at) %></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<% else %>
|
|
||||||
<p>There are no items to display.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<h3>Recent license updates</h3>
|
|
||||||
<% if licenses.length > 0 %>
|
|
||||||
<table class="u-full-width">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>License name</th>
|
|
||||||
<th>Updated at</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% licenses.each do |license| %>
|
|
||||||
<tr>
|
|
||||||
<td><%= license.name %></td>
|
|
||||||
<td><%= date_format(license.updated_at) %></td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<% else %>
|
|
||||||
<p>There are no licenses to display.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<h1>Add new IP address</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<form action="/ip-tracker/add" method="POST" class="u-full-width">
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="ip_address">IP address:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="192.168.1.20" id="ip_address" name="ip_address">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="ip_dns">DNS name:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="test.example.com" id="ip_dns" name="ip_dns">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<label for="ip_comment">Comments:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="My thoughts on this address..." id="ip_comment" name="ip_comment">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="button-primary u-full-width" type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,31 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<% if ip_addresses.length > 0 %>
|
|
||||||
<p><a href="/ip-tracker/add">Add new address</a></p>
|
|
||||||
<table class="u-full-width">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Address</th>
|
|
||||||
<th>DNS Name</th>
|
|
||||||
<th>Comments</th>
|
|
||||||
<th>Actions</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<% ip_addresses.each do |ip| %>
|
|
||||||
<tr>
|
|
||||||
<td><%= ip.address %></td>
|
|
||||||
<td><%= ip.dns_name %></td>
|
|
||||||
<td><%= ip.comment %></td>
|
|
||||||
<td>
|
|
||||||
<a href="/ip-tracker/delete/<%= ip.id %>"><i class="fa-solid fa-trash"></i></a>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<% end %>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<% else %>
|
|
||||||
<p>There are no IP addresses to show at this time. Trying <a href="/ip-tracker/add">adding some</a>.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,64 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<h1>Editing item: <%= item.name %></h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<form action="/item/<%= item.id %>/edit" method="POST" class="u-full-width">
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns twelve">
|
|
||||||
<label for="item_name">Item name:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="My new item" id="item_name" name="item_name" required value="<%= item.name %>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="item_serial">Serial number:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="0123456789" id="item_serial" name="item_serial" value="<%= item.serial_number %>">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="item_sku">SKU number:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="ABC12345678" id="item_sku" name="item_sku" value="<%= item.sku_number %>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="item_purchase_from">Purchased from:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="Newegg" id="item_purchase_from" name="item_purchase_from" value="<%= item.purchased_from %>">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="item_purchase_date">Purchased at:</label>
|
|
||||||
<input class="u-full-width" type="datetime-local" id="item_purchase_date" name="item_purchase_date" value="<%= date_format_input(item.purchased_at) %>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="item_manufacturer">Manufacturer:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="Manufacturer" id="item_manufacturer" name="item_manufacturer" value="<%= item.manufacturer %>">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="item_type">Item type</label>
|
|
||||||
<select class="u-full-width" id="item_type" name="item_type">
|
|
||||||
<option value="cpu" <%= item.type_selected?('cpu') %>>Processor</option>
|
|
||||||
<option value="motherboard" <%= item.type_selected?('motherboard') %>>Motherboard</option>
|
|
||||||
<option value="memory" <%= item.type_selected?('memory') %>>Memory (RAM)</option>
|
|
||||||
<option value="psu" <%= item.type_selected?('psu') %>>Power Supply</option>
|
|
||||||
<option value="case" <%= item.type_selected?('case') %>>Case</option>
|
|
||||||
<option value="storage" <%= item.type_selected?('storage') %>>Storage Device</option>
|
|
||||||
<option value="gpu" <%= item.type_selected?('gpu') %>>Graphics Card</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="button-primary u-full-width" type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,21 +1,7 @@
|
|||||||
<div class="row">
|
<p><a href="/item/create">Create new item</a></p>
|
||||||
<div class="twelve columns">
|
|
||||||
<h1>Hardware Inventory List</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
<ul>
|
||||||
<div class="twelve columns">
|
<% items.each do |item| %>
|
||||||
<p><a href="/item/create">Create new item</a></p>
|
<li><%= item.name %></li>
|
||||||
|
<% end %>
|
||||||
<% if items.length > 0 %>
|
</ul>
|
||||||
<ul>
|
|
||||||
<% items.each do |item| %>
|
|
||||||
<li><a href="/item/<%= item.id %>"><%= item.name %></a></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% else %>
|
|
||||||
<p>There is nothing registered in your inventory yet.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
@ -1,65 +0,0 @@
|
|||||||
<div id="item-header" class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<h1 class="item-name"><%= item.name %></h1>
|
|
||||||
<h4 class="item-created">Item added at: <%= date_format(item.created_at) %></h4>
|
|
||||||
<% if item.updated_at %>
|
|
||||||
<h4 class="item-updated">Last updated at: <%= date_format(item.updated_at) %></h4>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<p class="inventory-actions">
|
|
||||||
<a href="/item/<%= item.id %>/edit"><i class="fa-solid fa-pen-to-square"></i></a>
|
|
||||||
<a href="/item/<%= item.id %>/delete"><i class="fa-solid fa-trash"></i></a>
|
|
||||||
</p>
|
|
||||||
<table class="u-full-width">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Item type:</th>
|
|
||||||
<th>Manufacturer:</th>
|
|
||||||
<th>Serial number:</th>
|
|
||||||
<th>SKU number:</th>
|
|
||||||
<th>Vendor:</th>
|
|
||||||
<th>Purchase Date:</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><%= item.type %></td>
|
|
||||||
<td><%= nullable(item.manufacturer) %></td>
|
|
||||||
<td><%= nullable(item.serial_number) %></td>
|
|
||||||
<td><%= nullable(item.sku_number) %></td>
|
|
||||||
<td><%= nullable(item.purchased_from) %></td>
|
|
||||||
<td><%= nullable(date_format(item.purchased_at)) %></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<% if item.item_comments.length > 0 %>
|
|
||||||
<ul class="u-full-width">
|
|
||||||
<% item.item_comments.each do |comment| %>
|
|
||||||
<li><%= comment.body %></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% else %>
|
|
||||||
<p>There are no comments to display at this time.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<form action="/item/<%= item.id %>/comment" method="POST" class="u-full-width">
|
|
||||||
<label for="comment_body">Add a comment:</label>
|
|
||||||
<textarea name="comment_body" id="comment_body" class="u-full-width" cols="30" rows="10"></textarea>
|
|
||||||
|
|
||||||
<input class="button button-primary" type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -5,21 +5,21 @@
|
|||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title><%= title %> | Raven</title>
|
<title><%= title %> | Raven</title>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.2.1/css/all.min.css">
|
|
||||||
<link rel="stylesheet" href="/css/kraken.css">
|
<link rel="stylesheet" href="/css/kraken.css">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
||||||
<script src="/js/gargoyle.js"></script>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- Main navigation -->
|
<!-- Main navigation -->
|
||||||
<%= erb :'layout/navbar', :locals => locals %>
|
<nav id="main-nav">
|
||||||
<!-- Mobile navigatin -->
|
<h3>Raven</h3>
|
||||||
<%= erb :'layout/mobile_navbar', :locals => locals %>
|
<ul>
|
||||||
|
<li><a href="/">Dashboard</a></li>
|
||||||
|
<li><a href="/item/list">Items</a></li>
|
||||||
|
<li><a href="/license/list">Licenses</a></li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
|
||||||
<!-- Inventory search/actions bar -->
|
<div id="main-wrapper" class="container">
|
||||||
<%= erb :'layout/actions', :locals => locals %>
|
|
||||||
|
|
||||||
<div id="main-wrapper" class="container fluid card">
|
|
||||||
<%= yield %>
|
<%= yield %>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
<div id="main-actions" class="container fluid card">
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<form action="/search" class="u-full-width">
|
|
||||||
<input id="search-field" class="u-full-width" type="text" placeholder="Search your inventory..." name="query" required <%= defined?(query) ? 'value="' + query + '"' : '' %>>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,9 +0,0 @@
|
|||||||
<nav id="mobile-nav">
|
|
||||||
<span class="u-text-centered"><i id="mobile-nav-toggle" class="fa-solid fa-bars"></i></span>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Dashboard <i class="fa-solid fa-gauge"></i></a></li>
|
|
||||||
<li><a href="/item/list">Items <i class="fa-solid fa-desktop"></i></a></li>
|
|
||||||
<li><a href="/license/list">Licenses <i class="fa-solid fa-floppy-disk"></i></a></li>
|
|
||||||
<li><a href="/ip-tracker">IP Tracker <i class="fa-solid fa-network-wired"></i></a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
@ -1,9 +0,0 @@
|
|||||||
<nav id="main-nav">
|
|
||||||
<h3>Raven <i id="nav-toggle" class="fa-solid fa-bars"></i></h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="/">Dashboard <i class="fa-solid fa-gauge"></i></a></li>
|
|
||||||
<li><a href="/item/list">Items <i class="fa-solid fa-desktop"></i></a></li>
|
|
||||||
<li><a href="/license/list">Licenses <i class="fa-solid fa-floppy-disk"></i></a></li>
|
|
||||||
<li><a href="/ip-tracker">IP Tracker <i class="fa-solid fa-network-wired"></i></a></li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
@ -1,56 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<h1>Create new license</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<form action="/license/create" method="POST" class="u-full-width">
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns twelve">
|
|
||||||
<label for="license_name">Item name:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="My new license" id="license_name" name="license_name" required>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_key">License key:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="acbd1234efgh5678" id="license_key" required name="license_key">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_manufacturer">Manufacturer:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="Manufacturer" id="license_manufacturer" name="license_manufacturer">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_seats_used">Seats used on license:</label>
|
|
||||||
<input class="u-full-width" type="number" placeholder="0" id="license_seats_used" name="license_seats_used">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_seats_total">Total seats on license:</label>
|
|
||||||
<input class="u-full-width" type="number" placeholder="1" id="license_seats_total" name="license_seats_total">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_purchase_from">Purchased from:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="Newegg" id="license_purchase_from" name="license_purchase_from">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_purchase_date">Purchased at:</label>
|
|
||||||
<input class="u-full-width" type="datetime-local" id="license_purchase_date" name="license_purchase_date">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="button-primary u-full-width" type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,56 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<h1>Editing: <%= license.name %></h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<form action="/license/<%= license.id %>/edit" method="POST" class="u-full-width">
|
|
||||||
<div class="row">
|
|
||||||
<div class="columns twelve">
|
|
||||||
<label for="license_name">Item name:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="My new license" id="license_name" name="license_name" required value="<%= license.name %>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_key">License key:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="acbd1234efgh5678" id="license_key" name="license_key" required value="<%= license.key %>">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_manufacturer">Manufacturer:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="Manufacturer" id="license_manufacturer" name="license_manufacturer" value="<%= license.manufacturer %>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_seats_used">Seats used on license:</label>
|
|
||||||
<input class="u-full-width" type="number" placeholder="0" id="license_seats_used" name="license_seats_used" value="<%= license.seats_used %>">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_seats_total">Total seats on license:</label>
|
|
||||||
<input class="u-full-width" type="number" placeholder="1" id="license_seats_total" name="license_seats_total" value="<%= license.seats_total %>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_purchase_from">Purchased from:</label>
|
|
||||||
<input class="u-full-width" type="text" placeholder="Newegg" id="license_purchase_from" name="license_purchase_from" value="<%= license.purchased_from %>">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="six columns">
|
|
||||||
<label for="license_purchase_date">Purchased at:</label>
|
|
||||||
<input class="u-full-width" type="datetime-local" id="license_purchase_date" name="license_purchase_date" value="<%= date_format_input(license.purchased_at) %>">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<input class="button-primary u-full-width" type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,21 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<h1>Software Licenses List</h1>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<p><a href="/license/create">Create new license</a></p>
|
|
||||||
|
|
||||||
<% if licenses.length > 0 %>
|
|
||||||
<ul>
|
|
||||||
<% licenses.each do |license| %>
|
|
||||||
<li><a href="/license/<%= license.id %>"><%= license.name %></a></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% else %>
|
|
||||||
<p>There is nothing registered in your inventory yet.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,65 +0,0 @@
|
|||||||
<div id="license-header" class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<h1 class="license-name"><%= license.name %></h1>
|
|
||||||
<h4 class="license-created">License added at: <%= date_format(license.created_at) %></h4>
|
|
||||||
<% if license.updated_at %>
|
|
||||||
<h4 class="license-updated">Last updated at: <%= date_format(license.updated_at) %></h4>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<p class="inventory-actions">
|
|
||||||
<a href="/license/<%= license.id %>/edit"><i class="fa-solid fa-pen-to-square"></i></a>
|
|
||||||
<a href="/license/<%= license.id %>/delete"><i class="fa-solid fa-trash"></i></a>
|
|
||||||
</p>
|
|
||||||
<table class="u-full-width">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>License key:</th>
|
|
||||||
<th>Manufacturer:</th>
|
|
||||||
<th>Seats used:</th>
|
|
||||||
<th>Seats total:</th>
|
|
||||||
<th>Vendor:</th>
|
|
||||||
<th>Purchase Date:</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td><%= license.key %></td>
|
|
||||||
<td><%= nullable(license.manufacturer) %></td>
|
|
||||||
<td><%= nullable(license.seats_used) %></td>
|
|
||||||
<td><%= nullable(license.seats_total) %></td>
|
|
||||||
<td><%= nullable(license.purchased_from) %></td>
|
|
||||||
<td><%= nullable(date_format(license.purchased_at)) %></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<% if license.license_comments.length > 0 %>
|
|
||||||
<ul class="u-full-width">
|
|
||||||
<% license.license_comments.each do |comment| %>
|
|
||||||
<li><%= comment.body %></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% else %>
|
|
||||||
<p>There are no comments to display at this time.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<form action="/license/<%= license.id %>/comment" method="POST" class="u-full-width">
|
|
||||||
<label for="comment_body">Add a comment:</label>
|
|
||||||
<textarea name="comment_body" id="comment_body" class="u-full-width" cols="30" rows="10"></textarea>
|
|
||||||
|
|
||||||
<input class="button button-primary" type="submit" value="Submit">
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,14 +0,0 @@
|
|||||||
<div class="row">
|
|
||||||
<div class="twelve columns">
|
|
||||||
<h4>Matching inventory:</h4>
|
|
||||||
<% if results.length > 0 %>
|
|
||||||
<ul class="u-full-width">
|
|
||||||
<% results.each do |r| %>
|
|
||||||
<li><a href="<%= r.getLink() %>"><%= r.name %></a></li>
|
|
||||||
<% end %>
|
|
||||||
</ul>
|
|
||||||
<% else %>
|
|
||||||
<p>Sorry, nothing in your hardware inventory matches that search term.</p>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
Loading…
Reference in New Issue
Block a user