Skip to content

Commit

Permalink
Delete project and folders correctly. (#172)
Browse files Browse the repository at this point in the history
* fix problem on FF with scroll bars
* toolbar fix
* fix project deletion
* updated readme
* add license
  • Loading branch information
NickLaiacona authored Mar 13, 2019
1 parent a3b5000 commit 2e1b3b6
Show file tree
Hide file tree
Showing 8 changed files with 805 additions and 39 deletions.
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

93 changes: 80 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,24 +1,91 @@
# README
Digital Mappa v2.0
============================================

This README would normally document whatever steps are necessary to get the
application up and running.
Digital Mappa v2.0 (DM2 for short) is a freely available online environment for creating projects out of digital images and texts. The premise of DM2 is simple and powerful: if you have a collection of digital images and/or texts, you should be able to produce an online resource that links together specific moments on these images and texts together, annotate these moments as much as you want, collaborate with others on this work, have the content you produce be searchable, and publish this work to others or the public as you wish. And you should be able to do this with little technical expertise.

Things you may want to cover:
DM2 was developed under the direction of Martin Foys and his team at the University of Wisconsin-Madison and Dot Porter at the Schoenberg Institute for Manuscript Studies. Funding was provided through a grant from the National Endowment for the Humanities and through funding from UW Madison. Performant Software Solutions LLC (www.performantsoftware.com) performed the software developmemt, with Andy Stuhl and Nick Laiacona being the primary contributors to the 2.0 release.

* Ruby version
DM2 design was inspired by the DM project (https://github.com/performant-software/DM) developed originally at Drew University by Martin Foys and others.

* System dependencies

* Configuration
Technical Overview
---------------

* Database creation
DM2 is a single page React application backed by a Ruby on Rails server running a Postgres database. It uses ActiveStorage for image uploads and ImageMagick for image processing. It has out the box support for storing images either on Amazon S3 or on the local disk. It also utilizes the SendGrid service for outbound SMTP. It has been developed within the Heroku (heroku.com) environment but has no Heroku specific dependencies. Issues are tracked and relases are issued on the GitHub repo at https://github.com/performant-software/dm-2 .

* Database initialization

* How to run the test suite
Heroku Installation
-------------

* Services (job queues, cache servers, search engines, etc.)
To install DM2 on Heroku, create a new app and point it at this respository. You will need to provision SendGrid and Heroku PostGres. The following config variables should be set for the application:

AWS_ACCESS_KEY_ID
AWS_BUCKET
AWS_REGION
AWS_SECRET_ACCESS_KEY
HOSTNAME
LANG
RACK_ENV
RAILS_LOG_TO_STDOUT
RAILS_SERVE_STATIC_FILES
SENDGRID_PASSWORD
SENDGRID_USERNAME

You will also need to provision an Amazon S3 bucket to store the uploaded image files and configure access using Amazon IAM. See aws.amazon.com for more information.

Once these things are done, migrate the database using the following command:

heroku run rake db:migrate

DM2 should now be up and running on your Heroku instance!

The first user account created is automatically given admin powers. Thereafter, that user can grant other users access and privledges using the Admin menu in the top right corner of the interface.


Heroku Local Development Environment
-------------

DM2 is a pretty standard Ruby on Rails 5.x application. It uses a PostgreSQL and has been developed using PostgreSQL v11.1. It was developed using Ruby 2.5.1 and Bundler 1.16.5. Setting up PostgresSQL, Ruby, and Bundler are beyond the scope of this README, but plenty of information is available online about these tools.

Once the dependencies mentioned above are installed, please follow these steps:

1) Clone this repo to your local drive:

git clone https://github.com/performant-software/dm-2.git

2) Run bundler in the base directory to get all the Ruby dependencies:

bundle

3) Run yarn in the client directory to get all the JS dependencies:

cd client
yarn

4) Create a database for the application. The default database is called "dm2_staging" with no username or password. You can configure this in the config/database.yml file. Once the database is created, run:

rake db:migrate

5) Run the server with the following command:

heroku local -f Procfile.dev

Note that this runs two servers, one on port 3000 for Ruby on Rails and one on 3001 for the Create React App yarn server. This hot reloads any changes made to the Javascript files as you develop.

6) Visit http://localhost:3000 to view the application.

Please note that the development environment stores files on local disk in the /storage directory by default. You can configure different storage solutions in config/storage.yml. See the Rails ActiveStorage documentation for more details.


Installation without Heroku Toolset
-------------

Installation without the Heroku tool set is possible but requires setup specific to your enviroment. Follow the steps given above, except when it comes time to run the application, run the client and the server with these commands:

To run the client:
cd client && PORT=3000 yarn start

The run the server:
PORT=3001 && bundle exec puma -C config/puma.rb

* Deployment instructions

* ...
16 changes: 9 additions & 7 deletions app/models/concerns/tree_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ def remove_from_tree
ActiveRecord::Base.transaction do
i = 0
children.each { |child|
unless same_as( self, child )
child.position = i
i = i + 1
else
child.parent = nil
end
child.save!
unless child.destroyed?
unless same_as( self, child )
child.position = i
i = i + 1
else
child.parent = nil
end
child.save!
end
}
end
end
Expand Down
20 changes: 13 additions & 7 deletions app/models/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,23 @@ class Document < Linkable
include TreeNode

after_create :add_to_tree
before_destroy :remove_from_tree
# before_destroy :purge_images
before_destroy :destroyer

MAX_IMAGE_SIZE = 10
MAX_IMAGE_SIZE = 10 # MB

pg_search_scope :search_for, against: %i(title search_text)

# TODO this won't be called by delete_all - need a better way to clean up images
# def purge_images
# self.images.each { |image| image.purge }
# end
def destroyer
self.contents_children.each { |child|
child.destroy
}
remove_from_tree
purge_images
end

def purge_images
self.images.each { |image| image.purge }
end

# checks that all images validate, purges invalid images
def valid_images?
Expand Down
9 changes: 8 additions & 1 deletion app/models/document_folder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ class DocumentFolder < ApplicationRecord
include TreeNode

after_create :add_to_tree
before_destroy :remove_from_tree
before_destroy :destroyer

def destroyer
self.contents_children.each { |child|
child.destroy
}
remove_from_tree
end

def document_id
nil
Expand Down
14 changes: 11 additions & 3 deletions app/models/project.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
class Project < ApplicationRecord
belongs_to :owner, class_name: 'User', optional: true
has_many :documents, as: :parent, dependent: :delete_all
has_many :document_folders, as: :parent, dependent: :delete_all
has_many :user_project_permissions, dependent: :delete_all
has_many :documents, as: :parent
has_many :document_folders, as: :parent
has_many :user_project_permissions, dependent: :destroy
has_many :users, through: :user_project_permissions

default_scope { order(updated_at: :desc) }
scope :is_public, -> { where(public: true) }

before_destroy :destroyer

include TreeNode

def destroyer
self.contents_children.each { |child|
child.destroy
}
end

def can_read
self.users.merge(UserProjectPermission.read)
end
Expand Down
2 changes: 1 addition & 1 deletion client/src/ProseMirrorEditorView.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default class ProseMirrorEditorView extends Component {
render() {
// Render just an empty div which is then used as a container for an
// EditorView instance.
const style = { flexGrow: '1', overflowY: 'scroll', padding: '10px' };
const style = { flexGrow: '1', padding: '10px' };
return <div ref={this.props.createEditorView} style={style} />;
}
}
16 changes: 9 additions & 7 deletions client/src/TextResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -551,17 +551,19 @@ class TextResource extends Component {

render() {
const editorViewWrapperStyle = {
flexGrow: '1', display: 'flex', flexDirection: 'column'
flexGrow: '1', display: 'flex', flexDirection: 'column', overflowY: 'scroll', overflowX: 'hidden'
};

return (
<div className="editorview-wrapper" style={editorViewWrapperStyle}>
<div style={{flexGrow: '1', display: 'flex', flexDirection: 'column', overflow: 'hidden'}}>
{ this.props.writeEnabled ? this.renderToolbar() : "" }
<ProseMirrorEditorView
editorView={this.state.editorView}
createEditorView={this.createEditorView}
/>
{ this.renderLinkDialog() }
<div className="editorview-wrapper" style={editorViewWrapperStyle}>
<ProseMirrorEditorView
editorView={this.state.editorView}
createEditorView={this.createEditorView}
/>
{ this.renderLinkDialog() }
</div>
</div>
);
}
Expand Down

0 comments on commit 2e1b3b6

Please sign in to comment.