diff --git a/blocks/ORB/List.pm b/blocks/ORB/List.pm index 9e93853..dcea024 100644 --- a/blocks/ORB/List.pm +++ b/blocks/ORB/List.pm @@ -73,6 +73,8 @@ sub _build_recipe { }); } + my $time = ($recipe -> {"preptime"} + $recipe -> {"cooktime"}) * 60; + return $self -> {"template"} -> load_template("list/recipe.tem", { "%(id)s" => $recipe -> {"id"}, "%(url-view)s" => $self -> build_url(block => "view", @@ -80,7 +82,7 @@ sub _build_recipe { "%(name)s" => $recipe -> {"name"}, "%(type)s" => $recipe -> {"type"}, "%(status)s" => $recipe -> {"status"}, - "%(time)s" => $self -> {"template"} -> humanise_seconds($recipe -> {"timemins"} * 60, 1), + "%(time)s" => $self -> {"template"} -> humanise_seconds($time, 1), "%(temp)s" => $temp, "%(tags)s" => join("", map { $self -> _build_tag($_) } @{$recipe -> {"tags"}}), "%(controls)s" => $controls, diff --git a/blocks/ORB/New.pm b/blocks/ORB/New.pm index 523998d..e548b1c 100644 --- a/blocks/ORB/New.pm +++ b/blocks/ORB/New.pm @@ -85,17 +85,23 @@ sub _generate_new { my $ingredients = $self -> _build_ingredients($args); # Build up the type and status data - my $typeopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"types"} -> as_options(), + my $typeopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"types"} -> as_options(1), $args -> {"type"}); - my $statusopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"states"} -> as_options(0, visible => {value => 1}), + my $statusopts = $self -> {"template"} -> build_optionlist($self -> {"system"} -> {"entities"} -> {"states"} -> as_options(1, visible => {value => 1}), $args -> {"status"}); # Convert the time fields - my ($timemins, $timesecs) = ("", 0); - if($args -> {"timemins"}) { - $timesecs = $args -> {"timemins"} * 60; - $timemins = $self -> _build_timereq($timesecs); + my ($preptime, $prepsecs) = ("", 0); + if($args -> {"preptime"}) { + $prepsecs = $args -> {"preptime"} * 60; + $preptime = $self -> _build_timereq($prepsecs); + } + + my ($cooktime, $cooksecs) = ("", 0); + if($args -> {"cooktime"}) { + $cooksecs = $args -> {"cooktime"} * 60; + $cooktime = $self -> _build_timereq($cooksecs); } # Convert tags - can't use build_optionlist because all of them need to be selected. @@ -115,9 +121,11 @@ sub _generate_new { "%(name)s" => $args -> {"name"} // "", "%(source)s" => $args -> {"source"} // "", "%(yield)s" => $args -> {"yield"} // "", - "%(timereq)s" => $args -> {"timereq"} // "", - "%(timemins)s" => $timemins, - "%(timesecs)s" => $timesecs, + "%(prepinfo)s" => $args -> {"prepinfo"} // "", + "%(preptime)s" => $preptime, + "%(prepsecs)s" => $prepsecs, + "%(cooktime)s" => $cooktime, + "%(cooksecs)s" => $cooksecs, "%(temp)s" => $args -> {"temp"} // "", "%(temptypes)s" => $self -> {"template"} -> build_optionlist($temptypes, $args -> {"temptype"}), "%(types)s" => $typeopts, diff --git a/data/swagger.json b/data/swagger.json index 9097b37..76c0415 100755 --- a/data/swagger.json +++ b/data/swagger.json @@ -80,6 +80,44 @@ } } }, + "/recipes": { + "get": { + "tags": [ + "recipe" + ], + "summary": "Fetch a list of recipes defined in the system", + "description": "Retrieve the list of recipes defined in the system.\n", + "parameters": [ + { + "name": "name", + "description": "A name to search for recipes with", + "in": "query", + "type": "string", + "required": false + } + ], + "responses": { + "200": { + "description": "A list of recipes", + "schema": { + "$ref": "#/definitions/Recipes" + } + }, + "403": { + "description": "Permission error", + "schema": { + "$ref": "#/definitions/Error" + } + }, + "default": { + "description": "Unexpected error", + "schema": { + "$ref": "#/definitions/Error" + } + } + } + } + }, "/tags": { "get": { "tags": [ @@ -139,6 +177,15 @@ "$ref": "#/definitions/Ingredient" } }, + "Recipe": { + "type": "object" + }, + "Recipes": { + "type": "array", + "items": { + "$ref": "#/definitions/Recipe" + } + }, "Tag": { "type": "object", "properties": { diff --git a/data/swagger.yaml b/data/swagger.yaml index 1099991..9250897 100755 --- a/data/swagger.yaml +++ b/data/swagger.yaml @@ -43,14 +43,14 @@ paths: summary: Fetch the list of ingredients description: | Retrieve the list of ingredients defined in the system. - parameters: + parameters: - name: term description: A partial name to search for ingredients with in: query type: string required: false responses: - '200': + '200': description: A list of ingredients schema: $ref: '#/definitions/Ingredients' @@ -62,6 +62,32 @@ paths: description: Unexpected error schema: $ref: '#/definitions/Error' + /recipes: + get: + tags: + - recipe + summary: Fetch a list of recipes defined in the system + description: | + Retrieve the list of recipes defined in the system. + parameters: + - name: name + description: A name to search for recipes with + in: query + type: string + required: false + responses: + '200': + description: A list of recipes + schema: + $ref: '#/definitions/Recipes' + '403': + description: Permission error + schema: + $ref: '#/definitions/Error' + default: + description: Unexpected error + schema: + $ref: '#/definitions/Error' /tags: get: tags: @@ -69,14 +95,14 @@ paths: summary: Fetch a list of tags defined in the system description: | Retrieve the list of tags defined in the system. - parameters: + parameters: - name: term description: A partial name to search for tags with in: query type: string required: false responses: - '200': + '200': description: A list of tags schema: $ref: '#/definitions/Tags' @@ -102,10 +128,16 @@ definitions: type: array items: $ref: '#/definitions/Ingredient' + Recipe: + type: object + Recipes: + type: array + items: + $ref: '#/definitions/Recipe' Tag: type: object properties: - id: + id: type: number description: The ID of the tag in the system text: diff --git a/lang/en/recipe.lang b/lang/en/recipe.lang index 27bf656..ca77662 100644 --- a/lang/en/recipe.lang +++ b/lang/en/recipe.lang @@ -18,9 +18,13 @@ RECIPE_PREPINFO = Prep info RECIPE_PREPINFO_DOC = How much time each step of the recipe take? RECIPE_PREPINFO_PH = 10 min prep + 20 min cook -RECIPE_TIMEREQ = Time required -RECIPE_TIMEREQ_DOC = How long does this recipe take in total? -RECIPE_TIMEREQ_PH = 1 hour 10 minutes +RECIPE_PREPTIME = Preparation time required +RECIPE_PREPTIME_DOC = How long does this recipe take to prepare? +RECIPE_PREPTIME_PH = 30 minutes + +RECIPE_COOKTIME = Cooking time required +RECIPE_COOKTIME_DOC = How long does this recipe take to cook? +RECIPE_COOKTIME_PH = 30 minutes RECIPE_OVENTEMP = Oven preheat RECIPE_OVENTEMP_DOC = Initial oven temperature (show changes in method) diff --git a/modules/ORB.pm b/modules/ORB.pm index 1d7698c..f6c10c8 100755 --- a/modules/ORB.pm +++ b/modules/ORB.pm @@ -71,6 +71,16 @@ sub new { @_) or return undef; + # Formats of accepted types + $self -> {"formats"} = { + "recipename" => '^[-\w,. ]+$', + "tags" => '^[-\w ]+$', + "quantity" => '^[\d\w./]+$', + "sepname" => '^[-\w,. ]{1,255}$', + "ingredient" => '^[-\w,. ]{1,255}$', + "notes" => '^[-()\w,. ]{1,255}$', + }; + return $self; } diff --git a/modules/ORB/System/Entity.pm b/modules/ORB/System/Entity.pm index 4da8552..f1391e9 100644 --- a/modules/ORB/System/Entity.pm +++ b/modules/ORB/System/Entity.pm @@ -273,6 +273,8 @@ sub find_ids { # is no maximum and all possible matched are returned. # - `as`: can be set to `name`, `value`, or `text`. This determines the key # name used for the `name` field of the entities in the results. +# - `id`: can be set to `name` or `id`. This determines whether the entity name +# or id is used as the id in the data. # # @param args A hash or reference to a hash of search settings. # @return A reference to an array of hashes containing the results, ordered @@ -297,7 +299,13 @@ sub find { default { $as = "name"; } } - my $search = $self -> {"dbh"} -> prepare("SELECT `id`, `refcount`, `name` AS `$as` + my $id; + given($args -> {"id"}) { + when("name") { $id = "name"; } + default { $id = "id"; } + } + + my $search = $self -> {"dbh"} -> prepare("SELECT `$id` AS `id`, `refcount`, `name` AS `$as` FROM `".$self -> {"settings"} -> {"database"} -> {$self -> {"entity_table"}}."` WHERE `name` LIKE ? ORDER BY `name`,`id` diff --git a/modules/ORB/System/Recipe.pm b/modules/ORB/System/Recipe.pm index d260f9e..230c391 100644 --- a/modules/ORB/System/Recipe.pm +++ b/modules/ORB/System/Recipe.pm @@ -17,40 +17,7 @@ # along with this program. If not, see . ## @class Recipe -# +-------------+--------------------------------+------+-----+----------------+ -# | Field | Type | Null | Key | Extra | -# +-------------+--------------------------------+------+-----+----------------+ -# | id | int(10) unsigned | NO | PRI | auto_increment | -# | prev_id | int(11) | YES | | | -# | metadata_id | int(11) | NO | | | -# | name | varchar(80) | NO | UNI | | -# | method | text | NO | | | -# | notes | text | YES | | | -# | source | varchar(255) | YES | | | -# | yield | varchar(80) | NO | | | -# | timereq | varchar(255) | NO | | | -# | timemins | int(10) unsigned | NO | MUL | | -# | temptype | enum('C','F','Gas mark','N/A') | NO | | | -# | temp | smallint(5) unsigned | YES | | | -# | type_id | int(10) unsigned | NO | MUL | | -# | status_id | int(10) unsigned | NO | MUL | | -# | creator_id | int(10) unsigned | NO | | | -# | created | int(10) unsigned | NO | MUL | | -# | viewed | int(10) unsigned | NO | | | -# +-------------+--------------------------------+------+-----+----------------+ - -# +-----------+------------------+------+-----+----------------+ -# | Field | Type | Null | Key | Extra | -# +-----------+------------------+------+-----+----------------+ -# | id | int(10) unsigned | NO | PRI | auto_increment | -# | recipe_id | int(10) unsigned | NO | MUL | | -# | unit_id | int(10) unsigned | YES | | | -# | prep_id | int(10) unsigned | YES | | | -# | ingred_id | int(10) unsigned | YES | | | -# | quantity | varchar(8) | YES | | | -# | notes | varchar(255) | YES | | | -# | separator | varchar(255) | YES | | | -# +-----------+------------------+------+-----+----------------+ +# FIXME: corrected table schema here # # @@ -107,16 +74,14 @@ sub clear { # # - `id`: (optional, avoid) Set the ID to create the recipe with. # This should generally not be specified unless doing edits. -# - `previd`: (optional) ID of the recipe this is an edit of. If specified, -# the old recipe has its state set to 'edited', and the -# metadata context of the new recipe is created as a child of -# the old recipe to ensure editing works as expected. Generally +# - `origid`: (optional) ID of the recipe this is an edit of. Generally # this will not be specified directly; if editing a recipe, # call edit() to have renumbering handled for you. # - `name`: The name of the recipe # - `source`: (optional) Where did the recipe come from originally? -# - `timereq`: (optional) A string describing the time required for the recipe -# - `timemins`: How long does the recipe take in minutes, in total? +# - `prepinfo`: (optional) A string describing the time required for the recipe +# - `preptime`: How long does the recipe take to prepare in minutes? +# - `cooktime`: How long does the recipe take to cook in minutes? # - `yield`: A string describing how much stuff the recipe creates # - `temp`: (optional) Oven preheat temperature # - `temptype`: The type of units used: 'C', 'F', 'Gas mark', or 'N/A' @@ -170,19 +135,20 @@ sub create { unless($args -> {"created"}); # We need a metadata context for the recipe - my $metadataid = $self -> _create_recipe_metadata($args -> {"previd"}); + my $metadataid = $self -> _create_recipe_metadata($args -> {"origid"}); # Do the insert, and fetch the ID of the new row my $newh = $self -> {"dbh"} -> prepare("INSERT INTO `".$self -> {"settings"} -> {"database"} -> {"recipes"}."` - (`id`, `metadata_id`, `prev_id`, `name`, `source`, `timereq`, `timemins`, `yield`, `temp`, `temptype`, `method`, `notes`, `type_id`, `status_id`, `creator_id`, `created`, `updater_id`, `updated`) - VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,?)"); + (`id`, `metadata_id`, `original_id`, `name`, `source`, `prepinfo`, `preptime`, `cooktime`, `yield`, `temp`, `temptype`, `method`, `notes`, `type_id`, `status_id`, `creator_id`, `created`, `updater_id`, `updated`) + VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,?)"); my $result = $newh -> execute($args -> {"id"}, $metadataid, - $args -> {"previd"}, + $args -> {"origid"}, $args -> {"name"}, $args -> {"source"}, - $args -> {"timereq"}, - $args -> {"timemins"}, + $args -> {"prepinfo"}, + $args -> {"preptime"}, + $args -> {"cooktime"}, $args -> {"yield"}, $args -> {"temp"}, $args -> {"temptype"}, @@ -200,7 +166,8 @@ sub create { return $self -> self_error("No rows added when inserting recipe.") if($result eq "0E0"); - my $newid = $self -> {"dbh"} -> {"mysql_insertid"}; + # If we explicitly set an ID above, use it here rather than looking it up + my $newid = $args -> {"id"} // $self -> {"dbh"} -> {"mysql_insertid"}; return $self -> self_error("Unable to obtain id for new recipe") if(!$newid); @@ -228,7 +195,7 @@ sub create { # updated recipe overwrites the data at the old ID). # # @param args This should be a reference to a hash containing the same -# elements as the args hash for create(), except previd is +# elements as the args hash for create(), except origid is # required here. This should also contain the field # `updaterid` containing the ID of the user doing the edit. # @return The recipe Id on success, undef on error. @@ -238,15 +205,16 @@ sub edit { $self -> clear_error(); - return $self -> self_error("edit called without previous recipe ID") - unless($args -> {"previd"}); + return $self -> self_error("edit called without master recipe ID") + unless($args -> {"origid"}); - # Move the old recipe to the end of the table, but keep a record - # of its current ID - $args -> {"id"} = $args -> {"previd"}; - my $renumbered = $self -> _renumber_recipe($args -> {"id"}); + # We want the new recipe to get the same ID as the old one, so record it + $args -> {"id"} = $args -> {"origid"}; - # Create a new one at the old ID + # Now move the old recipe out of the way so the new one can use its ID + my $renumbered = $self -> _renumber_recipe($args -> {"id"}); + + # Create the new recipe at the old ID $self -> create($args) or return undef; @@ -256,6 +224,8 @@ sub edit { $args -> {"updaterid"}) or return undef; + + return $args -> {"id"}; } @@ -296,6 +266,31 @@ sub set_status { } +## @method $ set_viewed($recipeid, $viewerid) +# Update the 'viewed' timestamp for a recipe to show that a user has +# viewed it. +# +# @param recipeid The ID of the recipe that has been viewed. +# @param viewerid The ID of the user doing the viewing. +# @return true on success, undef on error. +sub set_viewed { + my $self = shift; + my $recipeid = shift; + my $viewerid = shift; + + $self -> clear_error(); + + my $updateh = $self -> {"dbh"} -> prepare("UPDATE `".$self -> {"settings"} -> {"database"} -> {"recipes"}."` + SET `viewed` = UNIX_TIMESTAMP() + WHERE `id` = ?"); + my $result = $updateh -> execute($recipeid); + return $self -> self_error("Update of recipe failed: ".$self -> {"dbh"} -> errstr) if(!$result); + return $self -> self_error("Recipe update failed: no rows updated") if($result eq "0E0"); + + return 1; +} + + # ============================================================================ # Recipe retrieval @@ -474,6 +469,8 @@ sub load_recipe_relations { # - `tagmatch`: control how tag searching works. As with `ingredmatch`, this # may be "all" or "any", with corresponding behaviour. # - `limit`: how many recipies may be returned by the find() +# - `original`: if set to true (the default) only search the most recent versions +# of recipes. If false, include edits. # - `offset`: offset from the start of the query results. # - `order`: optional ordering of results. Allowed values are 'added', 'updated', # 'viewed', or 'name' (the default). @@ -561,7 +558,16 @@ sub find { } # Squish all the where conditions into a string - my $wherecond = join(($args -> {"searchmode"} eq "any" ? "\nOR " : "\nAND "), @where) || "1"; + my $wherecond = join(($args -> {"searchmode"} eq "any" ? "\nOR " : "\nAND "), @where); + + # Unless `original` is false, we can only match the most recent edits + unless(defined($args -> {"original"}) && !$args -> {"original"}) { + $wherecond .= "\nAND" if($wherecond); + $wherecond .= "`r`.`original_id` IS NULL"; + } + + # Allow for no search criteria + $wherecond = "1" unless($wherecond); # Construct the limit term when limit (and optionally offset) are # specified by the caller @@ -666,7 +672,7 @@ sub _add_ingredients { } # Likewise for preparation methods - if($ingred -> {"prep"} && lc($ingred -> {"units"}) ne "none") { + if($ingred -> {"prep"} && lc($ingred -> {"prep"}) ne "none") { $prepid = $self -> {"entities"} -> {"prep"} -> get_id($ingred -> {"prep"}) or return $self -> self_error("Unable to get preparation method ID for '".$ingred -> {"prep"}."': ".$self -> {"entities"} -> {"prep"} -> errstr()); @@ -814,8 +820,8 @@ sub _renumber_recipe { # Duplicate the source recipe at the end of the table my $moveh = $self -> {"dbh"} -> prepare("INSERT INTO `".$self -> {"settings"} -> {"database"} -> {"recipes"}."` - (`metadata_id`, `prev_id`, `name`, `method`, `notes`, `source`, `yield`, `timereq`, `timemins`, `temptype`, `temp`, `type_id`, `status_id`, `creator_id`, `created`, `viewed`) - SELECT `metadata_id`, `prev_id`, `name`, `method`, `notes`, `source`, `yield`, `timereq`, `timemins`, `temptype`, `temp`, `type_id`, `status_id`, `creator_id`, `created`, `viewed` + (`metadata_id`, `name`, `method`, `notes`, `source`, `yield`, `prepinfo`, `preptime`, `cooktime`, `temptype`, `temp`, `type_id`, `status_id`, `creator_id`, `created`, `viewed`) + SELECT `metadata_id`, `name`, `method`, `notes`, `source`, `yield`, `prepinfo`, `preptime`, `cooktime`, `temptype`, `temp`, `type_id`, `status_id`, `creator_id`, `created`, `viewed` FROM `".$self -> {"settings"} -> {"database"} -> {"recipes"}."` WHERE `id` = ?"); my $rows = $moveh -> execute($sourceid); @@ -826,6 +832,7 @@ sub _renumber_recipe { my $newid = $self -> {"dbh"} -> {"mysql_insertid"} or return $self -> self_error("Unable to obtain id for new recipe"); + # Move all the old ingredient and tage relations to the copy we've just made $self -> _fix_recipe_relations($sourceid, $newid) or return undef; @@ -870,6 +877,13 @@ sub _fix_recipe_relations { $moveh -> execute($destid, $sourceid) or return $self -> self_error("Ingredient relation fixup failed: ".$self -> {"dbh"} -> errstr()); + # And set the original ID in the renumbered recipe + my $origh = $self -> {"dbh"} -> prepare("UPDATE `".$self -> {"settings"} -> {"database"} -> {"recipes"}."` + SET `original_id` = ? + WHERE `id` = ?"); + $origh -> execute($sourceid, $destid) + or return $self -> self_error("Ingredient origin fixup failed: ".$self -> {"dbh"} -> errstr()); + return 1; } @@ -1029,4 +1043,9 @@ sub _where_fragment { return $frag; } + + +sub _multi_where_fragment { + my $self = shift; +} 1; diff --git a/supportfiles/migrate_legacy_orb.pl b/supportfiles/migrate_legacy_orb.pl index bb9179a..1a7c6b9 100755 --- a/supportfiles/migrate_legacy_orb.pl +++ b/supportfiles/migrate_legacy_orb.pl @@ -11,6 +11,42 @@ use Webperl::ConfigMicro; use ORB::System; use Data::Dumper; +## @fn void clear_target_tables($dbh, $settings) +# Empty out tables in the new ORB database to allow easier reimport. +# +# @param dbh A reference to the new ORB database handle. +sub clear_target_tables { + my $dbh = shift; + my $settings = shift; + + # The tables to truncate + my @truncate = ( + 'convert', + 'ingredients', + 'prep', + 'recipes', + 'recipeing', + 'recipetags', + 'states', + 'tags', + 'types', + 'units' + ); + + foreach my $table (@truncate) { + $dbh -> do("TRUNCATE `".$settings -> {"database"} -> {$table}."`") + or die "Truncate failed: ".$dbh -> errstr."\n"; + } + + $dbh -> do("DELETE FROM `".$settings -> {"database"} -> {"metadata"}."` + WHERE `id` > 1") + or die "Metadata cleanup failed: ".$dbh -> errstr."\n"; + + $dbh -> do("ALTER TABLE `".$settings -> {"database"} -> {"metadata"}."` + AUTO_INCREMENT = 2") + or die "Metadata autoinc set failed: ".$dbh -> errstr."\n"; +} + ## @fn $ get_source_recipeids($dbh, $settings, $logger) # Fetch a list of recipie IDs in the source ORB database. @@ -174,8 +210,10 @@ sub convert_recipe { $recipe -> {"created"} = $recipe -> {"updated"}; # And fix up fields that need to do name mapping - $recipe -> {"type"} = $recipe -> {"typename"}; - $recipe -> {"status"} = $recipe -> {"statusname"}; + $recipe -> {"type"} = $recipe -> {"typename"}; + $recipe -> {"status"} = $recipe -> {"statusname"}; + $recipe -> {"prepinfo"} = $recipe -> {"timereq"}; + $recipe -> {"cooktime"} = $recipe -> {"timemins"}; # And go through the list of ingredients tweaking as needed foreach my $ingred (@{$recipe -> {"ingredients"}}) { @@ -189,6 +227,9 @@ sub convert_recipe { } } + # Nuke the source id + delete $recipe -> {"id"}; + return $recipe; } @@ -222,6 +263,8 @@ my $system = ORB::System -> new(dbh => $newdbh, $system -> init() or $logger -> die_log(undef, $system -> errstr()); +clear_target_tables($newdbh, $targetcfg); + my $rows = get_source_recipeids($olddbh, $legacycfg, $logger); foreach my $recipeid (@{$rows}) { diff --git a/templates/default/css/foundation.mods.css b/templates/default/css/foundation.mods.css index e1cd436..eab36fa 100755 --- a/templates/default/css/foundation.mods.css +++ b/templates/default/css/foundation.mods.css @@ -65,7 +65,8 @@ div.off-canvas .user { .pagemenu > li > a { width: 2rem; - padding: 0.75rem 0.75rem; + padding: 0.25rem 0.25rem; + display: inline-block; } .pagemenu > li.active > a { @@ -99,4 +100,8 @@ div.time-duration-picker-content td select { .spacer { margin-bottom: 1rem; -} \ No newline at end of file +} + +div.topspace { + margin-top: 0.5rem; +} diff --git a/templates/default/css/login.css b/templates/default/css/login.css index 596ed62..cdcd95b 100755 --- a/templates/default/css/login.css +++ b/templates/default/css/login.css @@ -2,7 +2,3 @@ div.contextlink { font-size: 0.75rem; } - -div.topspace { - margin-top: 0.5rem; -} diff --git a/templates/default/css/view.css b/templates/default/css/view.css index eb9f355..acbd264 100644 --- a/templates/default/css/view.css +++ b/templates/default/css/view.css @@ -1,5 +1,6 @@ div.recipe { margin: 0px 1.5rem; + width: 100%; } div.recipe h4 { @@ -8,6 +9,7 @@ div.recipe h4 { div.title { font-weight: bold; + white-space: nowrap; } div.ingredients ul { @@ -24,6 +26,7 @@ div.ingredients ul li.ingredient { } div.ingredients ul li.separator { + margin-left: 1rem; font-weight: bold; border-bottom: 1px solid #ccc; } diff --git a/templates/default/js/new.js b/templates/default/js/new.js index a103be2..4690eaa 100644 --- a/templates/default/js/new.js +++ b/templates/default/js/new.js @@ -1,3 +1,21 @@ +var CKCONFIG = { + font_names: 'Arial/Arial, Helvetica, sans-serif;' + + 'Book Antiqua/Book Antiqua, serif;'+ + 'Cambria/Cambria, serif;'+ + 'Courier New/Courier New, Courier, monospace;' + + 'Georgia/Georgia, serif;' + + 'Lucida Sans Unicode/Lucida Sans Unicode, Lucida Grande, sans-serif;' + + 'Tahoma/Tahoma, Geneva, sans-serif;' + + 'Times New Roman/Times New Roman, Times, serif;' + + 'Trebuchet MS/Trebuchet MS, Helvetica, sans-serif;' + + 'Verdana/Verdana, Geneva, sans-serif' +}; + +function check_name() +{ + var $name = $('#name').val(); + +} function add_separator() @@ -22,8 +40,43 @@ function add_ingredient(count) } +function build_ingdata() +{ + var values = new Array(); + + // Go through all the children of the ingredient list + // storing the value therein in elements of the values list + $('#ingredients').children().each(function() { + + // Is this a separator row? + if($(this).hasClass('separator')) { + var name = $(this).find('input.separator').val(); + + values.push({ "separator": true, + "name": name }); + } else { + var quantity = $(this).find('input.quantity').val(); + var units = $(this).find('select.units').val(); + var prep = $(this).find('select.preps').val(); + var name = $(this).find('input.ingredient').val(); + var notes = $(this).find('input.notes').val(); + + values.push({ "separator": false, + "quantity": quantity, + "units": units, + "prep": prep, + "name": name, + "notes": notes }); + + } + }); + + $('#ingdata').val(JSON.stringify({ "ingredients": values })); +} + + $(function() { - $('#timemins').timeDurationPicker({ + $('#preptime').timeDurationPicker({ lang: 'en_US', seconds: false, minutes: true, @@ -32,8 +85,22 @@ $(function() { months: false, years: false, onSelect: function(element, seconds, humanDuration) { - $('#timemins').val(humanDuration); - $('#timesecs').val(seconds); + $('#preptime').val(humanDuration); + $('#prepsecs').val(seconds); + console.log(seconds, humanDuration); + } + }); + $('#cooktime').timeDurationPicker({ + lang: 'en_US', + seconds: false, + minutes: true, + hours: true, + days: true, + months: false, + years: false, + onSelect: function(element, seconds, humanDuration) { + $('#cooktime').val(humanDuration); + $('#cooksecs').val(seconds); console.log(seconds, humanDuration); } }); @@ -51,8 +118,8 @@ $(function() { } }); - CKEDITOR.replace('method'); - CKEDITOR.replace('notes'); + CKEDITOR.replace('method', CKCONFIG); + CKEDITOR.replace('notes', CKCONFIG); $('#ingredients').sortable({ placeholder: "ui-state-highlight" @@ -71,4 +138,7 @@ $(function() { $('.deletectrl').on('click', function() { $(this).parents('li').fadeOut(300, function() { $(this).remove(); }); }); + + // Build the ingredient list before submitting + $('#newrecipe').on('submit', function() { build_ingdata(); return true }); }); diff --git a/templates/default/messagebox/box.tem b/templates/default/messagebox/box.tem index 7ab1af9..3cb7263 100755 --- a/templates/default/messagebox/box.tem +++ b/templates/default/messagebox/box.tem @@ -1,4 +1,4 @@ -
+

%(title)s

diff --git a/templates/default/new/content.tem b/templates/default/new/content.tem index a06baae..f1548de 100644 --- a/templates/default/new/content.tem +++ b/templates/default/new/content.tem @@ -19,13 +19,19 @@
-
+
+
diff --git a/templates/default/userbar/userbar.tem b/templates/default/userbar/userbar.tem index 745fc70..093283c 100755 --- a/templates/default/userbar/userbar.tem +++ b/templates/default/userbar/userbar.tem @@ -2,7 +2,7 @@