From 1805cb3e179adfaf54b678bff5b7874d970e49aa Mon Sep 17 00:00:00 2001 From: Paul Schneider Date: Sat, 17 Oct 2015 14:45:57 +0200 Subject: [PATCH] big refactoring, and more New routes, new juice flow, the tags on posts --- NpgsqlBlogProvider/ChangeLog | 4 + NpgsqlBlogProvider/NpgsqlBlogProvider.cs | 281 ++++++++++-------- web/NUnitTestClass.cs => TestAPI/AllTests.cs | 37 ++- TestAPI/BlogUnitTestCase.cs | 2 +- TestAPI/ChangeLog | 11 + .../DebugServer.cs | 48 +-- TestAPI/HelloWorld.cs | 73 +++++ ...countUnitTestCase.cs => ServerTestCase.cs} | 80 +++-- TestAPI/TestAPI.csproj | 50 +++- TestAPI/TestAutomate.cs | 2 + ...{Web.config => test-domain-TestAPI.config} | 0 web/ApiControllers/BlogsController.cs | 62 ++-- web/App_Themes/style.css | 130 ++++---- web/ChangeLog | 26 ++ web/Controllers/AccountController.cs | 14 +- web/Controllers/AdminController.cs | 8 +- web/Controllers/BlogsController.cs | 62 ++-- web/Controllers/GoogleController.cs | 4 +- web/Controllers/HomeController.cs | 2 +- web/Global.asax.cs | 26 +- web/Helpers/YavscHelpers.cs | 66 +++- web/Models/App.master | 29 +- web/Scripts/knockout-jqAutocomplete.js | 189 ++++++++++++ web/Scripts/knockout-jqAutocomplete.min.js | 2 + web/Scripts/yavsc.js | 29 +- web/Views/Blogs/Edit.aspx | 26 +- web/Views/Blogs/Index.aspx | 15 +- web/Views/Blogs/PageLinks.ascx | 8 + web/Views/Blogs/PostActions.ascx | 10 +- web/Views/Blogs/TagControl.ascx | 97 ++++++ web/Views/Blogs/Title.aspx | 4 +- web/Views/Blogs/UserPost.aspx | 3 +- web/Views/Blogs/UserPosts.aspx | 11 +- web/Views/FrontOffice/Estimate.aspx | 6 +- web/Web.csproj | 7 +- yavscModel/Blogs/BasePost.cs | 15 +- yavscModel/Blogs/BlogEntry.cs | 33 +- yavscModel/Blogs/BlogEntryCollection.cs | 17 +- yavscModel/Blogs/PostTag.cs | 45 +++ yavscModel/ChangeLog | 13 + yavscModel/LocalizedText.Designer.cs | 268 +++++++++-------- yavscModel/LocalizedText.fr.Designer.cs | 28 +- yavscModel/LocalizedText.fr.resx | 4 + yavscModel/LocalizedText.resx | 4 + yavscModel/WorkFlow/Automate.cs | 2 +- yavscModel/YavscModel.csproj | 1 + 46 files changed, 1339 insertions(+), 515 deletions(-) rename web/NUnitTestClass.cs => TestAPI/AllTests.cs (64%) create mode 100644 TestAPI/ChangeLog rename web/Scripts/yavsc.scrollnotif.js => TestAPI/DebugServer.cs (58%) create mode 100644 TestAPI/HelloWorld.cs rename TestAPI/{AccountUnitTestCase.cs => ServerTestCase.cs} (51%) rename TestAPI/{Web.config => test-domain-TestAPI.config} (100%) create mode 100644 web/Scripts/knockout-jqAutocomplete.js create mode 100644 web/Scripts/knockout-jqAutocomplete.min.js create mode 100644 web/Views/Blogs/PageLinks.ascx create mode 100644 web/Views/Blogs/TagControl.ascx create mode 100644 yavscModel/Blogs/PostTag.cs diff --git a/NpgsqlBlogProvider/ChangeLog b/NpgsqlBlogProvider/ChangeLog index a0a13022..647d5ebc 100644 --- a/NpgsqlBlogProvider/ChangeLog +++ b/NpgsqlBlogProvider/ChangeLog @@ -1,3 +1,7 @@ +2015-10-17 Paul Schneider + + * NpgsqlBlogProvider.cs: + 2015-10-13 Paul Schneider * NpgsqlBlogProvider.cs: implements the tag methods on db diff --git a/NpgsqlBlogProvider/NpgsqlBlogProvider.cs b/NpgsqlBlogProvider/NpgsqlBlogProvider.cs index 2f611ce8..70a090cd 100644 --- a/NpgsqlBlogProvider/NpgsqlBlogProvider.cs +++ b/NpgsqlBlogProvider/NpgsqlBlogProvider.cs @@ -33,8 +33,8 @@ namespace Npgsql.Web.Blog using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "INSERT INTO tagged (tagid,postid) VALUES (:tid,:pid)"; - cmd.Parameters.AddWithValue("tid",tid); - cmd.Parameters.AddWithValue("pid",postid); + cmd.Parameters.AddWithValue ("tid", tid); + cmd.Parameters.AddWithValue ("pid", postid); cnx.Open (); cmd.ExecuteNonQuery (); return tid; @@ -47,8 +47,9 @@ namespace Npgsql.Web.Blog /// Postid. /// Tagid. /// Name. - override public void Untag(long postid, string name) { - Untag(postid, GetTagId (name)); + override public void Untag (long postid, string name) + { + Untag (postid, GetTagId (name)); } /// @@ -57,7 +58,8 @@ namespace Npgsql.Web.Blog /// Postid. /// Tagid. /// Tid. - override public void Untag(long postid, long tid) { + override public void Untag (long postid, long tid) + { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "DELETE FROM tagged WHERE postid = :pid AND tagid = :tid"; @@ -67,6 +69,7 @@ namespace Npgsql.Web.Blog cmd.ExecuteNonQuery (); } } + /// /// Gets the comments. /// @@ -77,32 +80,33 @@ namespace Npgsql.Web.Blog { List cmts = new List (); - using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) - using (NpgsqlCommand cmd = cnx.CreateCommand()) { + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "select _id, username, bcontent, modified, posted, visible from comment " + - "where applicationname = :appname and postid = :id" + - ((getHidden) ? " and visible = true ":" ") + - "order by posted asc" ; + "where applicationname = :appname and postid = :id" + + ((getHidden) ? " and visible = true " : " ") + + "order by posted asc"; cmd.Parameters.AddWithValue ("appname", applicationName); cmd.Parameters.AddWithValue ("id", postid); cnx.Open (); - using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) { while (rdr.Read ()) { - Comment c = new Comment(); + Comment c = new Comment (); c.CommentText = rdr.GetString (rdr.GetOrdinal ("bcontent")); c.From = rdr.GetString (rdr.GetOrdinal ("username")); c.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); c.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); c.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); c.PostId = postid; - c.Id = rdr.GetInt64(rdr.GetOrdinal("_id")); + c.Id = rdr.GetInt64 (rdr.GetOrdinal ("_id")); cmts.Add (c); } } } - return cmts.ToArray(); + return cmts.ToArray (); } + /// /// Updates the post. /// @@ -112,9 +116,9 @@ namespace Npgsql.Web.Blog /// If set to true visible. /// Circle identifiers public override void UpdatePost (long postid, string title, string content, - bool visible, long [] cids) + bool visible, long[] cids) { - using (NpgsqlConnection cnx = new NpgsqlConnection(connectionString)) { + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { DateTime now = DateTime.Now; cmd.CommandText = @@ -131,10 +135,11 @@ namespace Npgsql.Web.Blog cnx.Open (); cmd.ExecuteNonQuery (); } - cnx.Close(); + cnx.Close (); } UpdatePostCircles (postid, cids); } + /// /// Removes the post. /// @@ -146,9 +151,10 @@ namespace Npgsql.Web.Blog cmd.CommandText = "delete from blog where _id = :id"; cmd.Parameters.AddWithValue ("id", postid); cnx.Open (); - cmd.ExecuteNonQuery(); + cmd.ExecuteNonQuery (); } } + /// /// Comment the specified from, postid and content. /// @@ -158,17 +164,17 @@ namespace Npgsql.Web.Blog public override long Comment (string from, long postid, string content) { if (from == null) - throw new ArgumentNullException("from"); + throw new ArgumentNullException ("from"); if (content == null) - throw new ArgumentNullException("content"); + throw new ArgumentNullException ("content"); bool visible = AutoValidatesComments; - using (NpgsqlConnection cnx= - new NpgsqlConnection(connectionString)) - using (NpgsqlCommand cmd = cnx.CreateCommand()) { + using (NpgsqlConnection cnx = + new NpgsqlConnection (connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "insert into comment (postid,bcontent," + - "modified,posted,visible,username,applicationname)" + - "values (:postid,:bcontent,:modified,:posted," + - ":visible,:username,:appname) returning _id"; + "modified,posted,visible,username,applicationname)" + + "values (:postid,:bcontent,:modified,:posted," + + ":visible,:username,:appname) returning _id"; cmd.Parameters.AddWithValue ("postid", postid); cmd.Parameters.AddWithValue ("bcontent", content); DateTime now = DateTime.Now; @@ -178,9 +184,10 @@ namespace Npgsql.Web.Blog cmd.Parameters.AddWithValue ("username", from); cmd.Parameters.AddWithValue ("appname", applicationName); cnx.Open (); - return (long) cmd.ExecuteScalar(); + return (long)cmd.ExecuteScalar (); } } + /// /// Validates the comment. /// @@ -189,6 +196,7 @@ namespace Npgsql.Web.Blog { throw new NotImplementedException (); } + /// /// Updates the comment. /// @@ -202,6 +210,7 @@ namespace Npgsql.Web.Blog } private bool autoValidateComment = true; + /// /// Gets or sets a value indicating whether this auto validate comment. /// @@ -211,7 +220,7 @@ namespace Npgsql.Web.Blog return autoValidateComment; } set { - autoValidateComment=value; + autoValidateComment = value; } } @@ -227,6 +236,7 @@ namespace Npgsql.Web.Blog } #endregion + /// /// Initialize the specified name and config. /// @@ -240,10 +250,12 @@ namespace Npgsql.Web.Blog config.Remove ("connectionStringName"); applicationName = config ["applicationName"]; config.Remove ("applicationName"); - defaultPageSize = int.Parse ( config ["pageLen"] ?? "10") ; + defaultPageSize = int.Parse (config ["pageLen"] ?? "10"); base.Initialize (name, config); } + #region implemented abstract members of BlogProvider + /// /// Gets the post. /// @@ -252,14 +264,14 @@ namespace Npgsql.Web.Blog public override BlogEntry GetPost (long postid) { BlogEntry be = null; - using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) - using (NpgsqlCommand cmd = cnx.CreateCommand()) { + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "select username, title, bcontent, modified, posted, visible, photo from blog " + - "where applicationname = :appname and _id = :id"; + "where applicationname = :appname and _id = :id"; cmd.Parameters.AddWithValue ("appname", applicationName); cmd.Parameters.AddWithValue ("id", postid); cnx.Open (); - using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) { if (rdr.Read ()) { be = new BlogEntry (); be.Title = rdr.GetString (rdr.GetOrdinal ("title")); @@ -269,16 +281,18 @@ namespace Npgsql.Web.Blog be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); int oph = rdr.GetOrdinal ("photo"); - if (!rdr.IsDBNull(oph)) + if (!rdr.IsDBNull (oph)) be.Photo = rdr.GetString (oph); be.Id = postid; } } } - if (be!=null) Populate (be); + if (be != null) + Populate (be); return be; } + /// /// Removes the comment. /// @@ -292,10 +306,11 @@ namespace Npgsql.Web.Blog cmd.CommandText = "delete from comment where _id = :id returning postid"; cmd.Parameters.AddWithValue ("id", cmtid); cnx.Open (); - postid = (long) cmd.ExecuteScalar (); + postid = (long)cmd.ExecuteScalar (); } return postid; } + /// /// Gets the post. /// @@ -304,13 +319,13 @@ namespace Npgsql.Web.Blog /// Title. public override UUTBlogEntryCollection GetPost (string username, string title) { - UUTBlogEntryCollection bec = new UUTBlogEntryCollection (username,title); + UUTBlogEntryCollection bec = new UUTBlogEntryCollection (username, title); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "select _id,bcontent,modified,posted,visible,photo from blog " + "where applicationname = :appname and username = :username and title = :title"; cmd.Parameters.AddWithValue ("appname", NpgsqlDbType.Varchar, applicationName); - cmd.Parameters.AddWithValue ("username", NpgsqlDbType.Varchar ,username); + cmd.Parameters.AddWithValue ("username", NpgsqlDbType.Varchar, username); cmd.Parameters.AddWithValue ("title", NpgsqlDbType.Varchar, title); cnx.Open (); cmd.Prepare (); @@ -352,19 +367,20 @@ namespace Npgsql.Web.Blog be.Tags = tags.ToArray (); } } - if (bec!=null) Populate (bec); + if (bec != null) + Populate (bec); } } return bec; } - private void SetCirclesOn(BlogEntry be) + private void SetCirclesOn (BlogEntry be) { List circles = new List (); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) using (NpgsqlCommand cmdcircles = cnx.CreateCommand ()) { cmdcircles.CommandText = "select a.circle_id from blog_access a " + - "where a.post_id = :pid"; + "where a.post_id = :pid"; cmdcircles.Parameters.AddWithValue ("pid", be.Id); cnx.Open (); using (NpgsqlDataReader rdr = cmdcircles.ExecuteReader ()) { @@ -380,12 +396,12 @@ namespace Npgsql.Web.Blog /// Removes the tag. /// /// Tagid. - public override void DropTag(long tagid) + public override void DropTag (long tagid) { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "DELETE from public.tag where _id = :tid"; - cmd.Parameters.AddWithValue("tagid",tagid); + cmd.Parameters.AddWithValue ("tagid", tagid); cnx.Open (); cmd.ExecuteNonQuery (); cnx.Close (); @@ -393,7 +409,9 @@ namespace Npgsql.Web.Blog } private static string SelectTagsSql = "SELECT tag.name, tag._id FROM public.tag WHERE name like :name"; - private IEnumerable GetSuggestion (string pattern) { + + private IEnumerable GetSuggestion (string pattern) + { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = SelectTagsSql; @@ -402,7 +420,8 @@ namespace Npgsql.Web.Blog } private static string InsertTagSql = "INSERT INTO tag (name) VALUES (:name) returning _id"; - private void InsertTag(long postid, long tagid) + + private void InsertTag (long postid, long tagid) { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) using (NpgsqlCommand cmd = cnx.CreateCommand ()) { @@ -410,8 +429,8 @@ namespace Npgsql.Web.Blog throw new NotImplementedException (); } } - - private long GetTagId(string tagname) + + private long GetTagId (string tagname) { long id = 0; using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) @@ -419,20 +438,30 @@ namespace Npgsql.Web.Blog cmd.CommandText = "SELECT tag._id FROM public.tag WHERE name = :name"; cmd.Parameters.AddWithValue ("name", tagname); cnx.Open (); - id = (long) cmd.ExecuteScalar (); + id = (long)cmd.ExecuteScalar (); } return id; } - private long GetOrCreateTagId(string tagname) + + private long GetOrCreateTagId (string tagname) { long id = 0; - using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) - using (NpgsqlCommand cmd = cnx.CreateCommand ()) { - cmd.CommandText = "SELECT tag._id FROM public.tag WHERE name = :name;\n" + - "IF NOT FOUND THEN INSERT INTO tag (name) values (:name) RETURNING _id; ENDIF;\n"; - cmd.Parameters.AddWithValue ("name", tagname); - cnx.Open (); - id = (long) cmd.ExecuteScalar (); + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { + try { + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = "SELECT tag._id FROM public.tag WHERE name = :name"; + cmd.Parameters.AddWithValue ("name", tagname); + cnx.Open (); + id = (long)cmd.ExecuteScalar (); + } + } catch (NullReferenceException) { + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = "INSERT INTO public.tag(name) VALUES (:name) RETURNING _id"; + cmd.Parameters.AddWithValue ("name", tagname); + cnx.Open (); + id = (long)cmd.ExecuteScalar (); + } + } } return id; } @@ -440,13 +469,16 @@ namespace Npgsql.Web.Blog private static string SelectPostTagsSql = "SELECT tag.name FROM public.tag, public.tagged\n" + - "WHERE tag._id = tagged.tagid AND tagged.postid = :pid \n"; - private void SetTagsOn(BlogEntryCollection bec){ + "WHERE tag._id = tagged.tagid AND tagged.postid = :pid \n"; + + private void SetTagsOn (BlogEntryCollection bec) + { foreach (BlogEntry be in bec) { SetTagsOn (be); } } - private void SetTagsOn(BlogEntry be) + + private void SetTagsOn (BlogEntry be) { List tags = new List (); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) @@ -464,16 +496,18 @@ namespace Npgsql.Web.Blog } // Assert(bec!=null); - private void Populate(BlogEntryCollection bec) + private void Populate (BlogEntryCollection bec) { - foreach (BlogEntry be in bec) Populate(be); + foreach (BlogEntry be in bec) + Populate (be); } - private void Populate(BlogEntry be) + private void Populate (BlogEntry be) { SetTagsOn (be); SetCirclesOn (be); } + /// /// Post the specified username, title, content and visible. /// @@ -482,15 +516,15 @@ namespace Npgsql.Web.Blog /// Content. /// If set to true visible. /// . - public override long Post (string username, string title, string content, bool visible, long [] circles) + public override long Post (string username, string title, string content, bool visible, long[] circles) { long pid = 0; if (username == null) - throw new ArgumentNullException("username"); + throw new ArgumentNullException ("username"); if (title == null) - throw new ArgumentNullException("title"); + throw new ArgumentNullException ("title"); if (content == null) - throw new ArgumentNullException("content"); + throw new ArgumentNullException ("content"); using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "insert into blog (title,bcontent,modified,posted,visible,username,applicationname)" + @@ -511,12 +545,13 @@ namespace Npgsql.Web.Blog UpdatePostCircles (pid, circles); return pid; } + /// /// Updates the post photo. /// /// Pid. /// Photo. - public override void UpdatePostPhoto ( long pid, string photo) + public override void UpdatePostPhoto (long pid, string photo) { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); @@ -530,7 +565,7 @@ namespace Npgsql.Web.Blog } } - private void UpdatePostCircles( long pid, long[] circles) + private void UpdatePostCircles (long pid, long[] circles) { using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) { cnx.Open (); @@ -539,21 +574,22 @@ namespace Npgsql.Web.Blog cmd.Parameters.AddWithValue ("pid", pid); cmd.ExecuteNonQuery (); } - if (circles!=null) - if (circles.Length>0) - using (NpgsqlCommand cmd = cnx.CreateCommand ()) { - cmd.CommandText = "insert into blog_access (post_id,circle_id) values (:pid,:cid)"; - cmd.Parameters.AddWithValue ("pid", NpgsqlTypes.NpgsqlDbType.Bigint, pid); - cmd.Parameters.Add ("cid", NpgsqlTypes.NpgsqlDbType.Bigint); - cmd.Prepare (); - foreach (long ci in circles) { - cmd.Parameters ["cid"].Value = ci; - cmd.ExecuteNonQuery (); + if (circles != null) + if (circles.Length > 0) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { + cmd.CommandText = "insert into blog_access (post_id,circle_id) values (:pid,:cid)"; + cmd.Parameters.AddWithValue ("pid", NpgsqlTypes.NpgsqlDbType.Bigint, pid); + cmd.Parameters.Add ("cid", NpgsqlTypes.NpgsqlDbType.Bigint); + cmd.Prepare (); + foreach (long ci in circles) { + cmd.Parameters ["cid"].Value = ci; + cmd.ExecuteNonQuery (); + } } - } cnx.Close (); } } + /// /// Finds the post. /// @@ -568,40 +604,40 @@ namespace Npgsql.Web.Blog { BlogEntryCollection c = new BlogEntryCollection (); totalRecords = 0; - using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) - using (NpgsqlCommand cmd = cnx.CreateCommand()) { + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { if (readersName != null) { cmd.CommandText = "select _id, title,bcontent, modified," + - "posted,username,visible,photo " + - "from blog b left outer join " + - "(select count(*)>0 acc, a.post_id pid " + - "from blog_access a," + - " circle_members m, users u where m.circle_id = a.circle_id " + - " and m.member = u.username and u.username = :uname " + - " and u.applicationname = :appname " + - " group by a.post_id) ma on (ma.pid = b._id) " + - "where ( ((ma.acc IS NULL or ma.acc = TRUE) and b.Visible IS TRUE ) or b.username = :uname) "; + "posted,username,visible,photo " + + "from blog b left outer join " + + "(select count(*)>0 acc, a.post_id pid " + + "from blog_access a," + + " circle_members m, users u where m.circle_id = a.circle_id " + + " and m.member = u.username and u.username = :uname " + + " and u.applicationname = :appname " + + " group by a.post_id) ma on (ma.pid = b._id) " + + "where ( ((ma.acc IS NULL or ma.acc = TRUE) and b.Visible IS TRUE ) or b.username = :uname) "; cmd.Parameters.AddWithValue ("uname", readersName); } else { cmd.CommandText = "select _id, title,bcontent,modified," + - "posted,username,visible,photo " + - "from blog b left outer join " + - "(select count(*)>0 acc, a.post_id pid " + - "from blog_access a" + - " group by a.post_id) ma on (ma.pid = b._id)" + - " where " + - " ma.acc IS NULL and " + - " b.Visible IS TRUE and " + - " applicationname = :appname"; + "posted,username,visible,photo " + + "from blog b left outer join " + + "(select count(*)>0 acc, a.post_id pid " + + "from blog_access a" + + " group by a.post_id) ma on (ma.pid = b._id)" + + " where " + + " ma.acc IS NULL and " + + " b.Visible IS TRUE and " + + " applicationname = :appname"; } cmd.Parameters.AddWithValue ("appname", applicationName); if (pattern != null) { if ((searchflags & FindBlogEntryFlags.MatchTag) > 0) { cmd.CommandText += "AND EXISTS (SELECT tag._id FROM public.tag, public.tagged WHERE " + - "public.tag._id = public.tagged.tagid " + - "AND public.tagged.postid = a.post_id " + - "public.tag.name like :tagname) "; + "public.tag._id = public.tagged.tagid " + + "AND public.tagged.postid = a.post_id " + + "public.tag.name like :tagname) "; cmd.Parameters.AddWithValue ("tagname", pattern); } @@ -624,11 +660,11 @@ namespace Npgsql.Web.Blog cmd.CommandText += " order by posted desc"; cnx.Open (); - using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) { // pageIndex became one based int firstrec = pageIndex * pageSize; int lastrec = firstrec + pageSize - 1; - while (rdr.Read()) { + while (rdr.Read ()) { if (totalRecords >= firstrec && totalRecords <= lastrec) { BlogEntry be = new BlogEntry (); be.Title = rdr.GetString (rdr.GetOrdinal ("title")); @@ -637,7 +673,7 @@ namespace Npgsql.Web.Blog be.Author = rdr.GetString (rdr.GetOrdinal ("username")); be.Posted = rdr.GetDateTime (rdr.GetOrdinal ("posted")); be.Modified = rdr.GetDateTime (rdr.GetOrdinal ("modified")); - be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); + be.Visible = rdr.GetBoolean (rdr.GetOrdinal ("visible")); { int oph = rdr.GetOrdinal ("photo"); if (!rdr.IsDBNull (oph)) @@ -650,10 +686,12 @@ namespace Npgsql.Web.Blog rdr.Close (); } } - if (c!=null) Populate (c); + if (c != null) + Populate (c); return c; } + /// /// Removes the post. /// @@ -661,20 +699,21 @@ namespace Npgsql.Web.Blog /// Title. public override void RemoveTitle (string username, string title) { - using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) - using (NpgsqlCommand cmd = cnx.CreateCommand()) { + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "delete from blog where username = :username and applicationname = :appname and title=:title"; - cmd.Parameters.AddWithValue ("username",username); + cmd.Parameters.AddWithValue ("username", username); cmd.Parameters.AddWithValue ("appname", applicationName); - cmd.Parameters.AddWithValue ("title",title); + cmd.Parameters.AddWithValue ("title", title); cnx.Open (); cmd.ExecuteNonQuery (); - cnx.Close(); + cnx.Close (); } } int defaultPageSize = 10; + /// /// Lasts the posts. /// @@ -682,23 +721,23 @@ namespace Npgsql.Web.Blog /// Page index. /// Page size. /// Total records. - public override BlogEntryCollection LastPosts(int pageIndex, int pageSize, out int totalRecords) + public override BlogEntryCollection LastPosts (int pageIndex, int pageSize, out int totalRecords) { BlogEntryCollection c = new BlogEntryCollection (); - using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString)) - using (NpgsqlCommand cmd = cnx.CreateCommand()) { + using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) + using (NpgsqlCommand cmd = cnx.CreateCommand ()) { cmd.CommandText = "select * " + - "from blog where applicationname = :appname and visible = true " + - " order by posted desc limit :len" ; + "from blog where applicationname = :appname and visible = true " + + " order by posted desc limit :len"; cmd.Parameters.AddWithValue ("appname", applicationName); - cmd.Parameters.AddWithValue ("len", defaultPageSize*10); + cmd.Parameters.AddWithValue ("len", defaultPageSize * 10); cnx.Open (); - using (NpgsqlDataReader rdr = cmd.ExecuteReader()) { + using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) { totalRecords = 0; int firstrec = pageIndex * pageSize; int lastrec = firstrec + pageSize - 1; - while (rdr.Read()) { + while (rdr.Read ()) { if (totalRecords >= firstrec && totalRecords <= lastrec) { BlogEntry be = new BlogEntry (); be.Id = rdr.GetInt64 (rdr.GetOrdinal ("_id")); @@ -719,9 +758,11 @@ namespace Npgsql.Web.Blog } } } - if (c!=null) Populate (c); + if (c != null) + Populate (c); return c; } + #endregion } } diff --git a/web/NUnitTestClass.cs b/TestAPI/AllTests.cs similarity index 64% rename from web/NUnitTestClass.cs rename to TestAPI/AllTests.cs index c5f511b3..35580461 100644 --- a/web/NUnitTestClass.cs +++ b/TestAPI/AllTests.cs @@ -1,5 +1,5 @@ -// -// NUnitTestClass.cs +// +// AllTests.cs // // Author: // Paul Schneider @@ -18,24 +18,35 @@ // // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . + using NUnit.Framework; using System; +using Yavsc.Model.Blogs; +using Yavsc.Controllers; +using System.Web.Mvc; +using System.Web.Security; +using System.Web.Configuration; +using System.Configuration; +using System.IO; +using System.Web.Http; +using Mono.WebServer; +using System.Net; +using System.Collections; namespace Yavsc { - /// - /// N unit test class. - /// - [TestFixture ()] - public class NUnitTestClass + public class AllTests { - /// - /// Tests the case. - /// - [Test ()] - public void TestCase () + [Suite] + public static IEnumerable Suite { + get + { + ArrayList suite = new ArrayList (); + suite.Add(new BlogUnitTestCase()); + return suite; + } } } + } - diff --git a/TestAPI/BlogUnitTestCase.cs b/TestAPI/BlogUnitTestCase.cs index 4836f416..386d3fbe 100644 --- a/TestAPI/BlogUnitTestCase.cs +++ b/TestAPI/BlogUnitTestCase.cs @@ -25,7 +25,7 @@ using Yavsc.Model.Blogs; namespace Yavsc { [TestFixture ()] - public class BlogUnitTestCase: AccountUnitTestCase + public class BlogUnitTestCase: ServerTestCase { [TestFixtureSetUp] diff --git a/TestAPI/ChangeLog b/TestAPI/ChangeLog new file mode 100644 index 00000000..62d6bb37 --- /dev/null +++ b/TestAPI/ChangeLog @@ -0,0 +1,11 @@ +2015-10-17 Paul Schneider + + * AllTests.cs: + * HelloWorld.cs: + * DebugServer.cs: + * TestAPI.csproj: + * TestAutomate.cs: + * ServerTestCase.cs: + * BlogUnitTestCase.cs: + * test-domain-TestAPI.config: + diff --git a/web/Scripts/yavsc.scrollnotif.js b/TestAPI/DebugServer.cs similarity index 58% rename from web/Scripts/yavsc.scrollnotif.js rename to TestAPI/DebugServer.cs index 646e82e2..536c0cf7 100644 --- a/web/Scripts/yavsc.scrollnotif.js +++ b/TestAPI/DebugServer.cs @@ -1,5 +1,5 @@ -// -// parralax.js +// +// DebugServer.cs // // Author: // Paul Schneider @@ -19,19 +19,33 @@ // You should have received a copy of the GNU Lesser General Public License // along with this program. If not, see . -$(document).ready(function(){ - var $window = $(window); - $(window).scroll(function() { - var $ns = $('#notifications'); - if ($ns.has('*').length>0) { - if ($window.scrollTop()>375) { - $ns.css('position','fixed'); - $ns.css('z-index',2); - $ns.css('top',0); +using System; +using NUnit.Framework; +using System.Net; +using Mono.WebServer.XSP; + +namespace Mono.WebServer.Test +{ + + public class DebugServer : IDisposable + { + #region IDisposable implementation + + public void Dispose () + { + // would have a sense when managing the Xsp server instance: + // server.Stop(); + } + + #endregion + + string physicalPath = @"/home/paul/workspace/totem/web/"; + + public int Run () + { + + return Server.Main (new [] { "--applications", "/:"+physicalPath, "--port", "8080", "--nonstop" }); } - else { - $ns.css('position','static'); - $ns.css('z-index',1); - }} - }); -}); + } + +} \ No newline at end of file diff --git a/TestAPI/HelloWorld.cs b/TestAPI/HelloWorld.cs new file mode 100644 index 00000000..f6703cc7 --- /dev/null +++ b/TestAPI/HelloWorld.cs @@ -0,0 +1,73 @@ +// +// HelloWorld.cs +// +// +// HelloWorld.cs +// +// Author: +// Leonardo Taglialegne +// +// Copyright (c) 2013 Leonardo Taglialegne. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using NUnit.Framework; +using System.Net; +using Mono.WebServer.XSP; + +namespace Mono.WebServer.Test +{ + + + [TestFixture] + public class HelloWorld + { + + [Test] + public void TestCase () + { + using (var server = new DebugServer()) { + Assert.AreEqual (0, server.Run ()); + var wc = new WebClient (); + try { + string downloaded = wc.DownloadString ("http://localhost:8080/"); + //Assert.AreEqual (Environment.CurrentDirectory, downloaded); + // ResponseHeaders { + // Date: Thu, 15 Oct 2015 16:12:00 GMT + // Server: Mono.WebServer.XSP/3.8.0.0 Linux + // X-AspNetMvc-Version: 3.0 + // X-AspNet-Version: 4.0.30319 + // Content-Length: 2180 + // Cache-Control: private + // Content-Type: text/html + // Set-Cookie: ASP.NET_SessionId=ED208D636A4312B9745E396D; path=/ + // Keep-Alive: timeout=15, max=100 + // Connection: Keep-Alive } System.Net.WebHeaderCollection + Assert.Greater(wc.ResponseHeaders["Set-Cookie"].Length, 10); + + } catch (WebException e) { + Assert.Fail (e.Message); + } + } + } + } +} \ No newline at end of file diff --git a/TestAPI/AccountUnitTestCase.cs b/TestAPI/ServerTestCase.cs similarity index 51% rename from TestAPI/AccountUnitTestCase.cs rename to TestAPI/ServerTestCase.cs index 78679641..02359035 100644 --- a/TestAPI/AccountUnitTestCase.cs +++ b/TestAPI/ServerTestCase.cs @@ -28,12 +28,17 @@ using System.Web.Configuration; using System.Configuration; using System.IO; using System.Web.Http; +using Mono.WebServer; +using System.Net; +using System.Web.Hosting; +using Mono.Web.Util; +using Mono.WebServer.Options; namespace Yavsc { [TestFixture ()] - public class AccountUnitTestCase + public class ServerTestCase { public string UserName { get; set; } @@ -47,33 +52,70 @@ namespace Yavsc return accountController; } } + + ApplicationServer WebAppServer; + string defaultMembershipProvider = null; + [Test] - public virtual void Init() + public virtual void Start() { - webSource = new XSPWebSource (configurationManager.Address, configurationManager.Port, !root); - + // get the web config + string physicalPath = @"/home/paul/workspace/totem/web/"; + string physicalPathToConfig = physicalPath + "/Web.config"; + ExeConfigurationFileMap exemap = new ExeConfigurationFileMap (); + exemap.ExeConfigFilename = physicalPathToConfig ; + Configuration config = System.Configuration.ConfigurationManager.OpenMappedExeConfiguration (exemap, ConfigurationUserLevel.None); + - var server = new ApplicationServer (webSource, configurationManager.Root) { - Verbose = configurationManager.Verbose, - SingleApplication = !root - }; string basedir = AppDomain.CurrentDomain.BaseDirectory; string curdir = Directory.GetCurrentDirectory (); string dummyVirtualPath = "/"; - string physicalPath = @"/home/paul/workspace/totem/web/"; - WebConfigurationFileMap map = new WebConfigurationFileMap (); - map.VirtualDirectories.Add(dummyVirtualPath, new VirtualDirectoryMapping(physicalPath, true)); - Configuration configuration = WebConfigurationManager.OpenMappedWebConfiguration(map, dummyVirtualPath); - accountController = new AccountController (); - string da = (string) configuration.AppSettings.Settings ["DefaultAvatar"].Value; - MembershipSection s = configuration.GetSection ("system.web/membership") as MembershipSection; - defaultMembershipProvider = s.DefaultProvider; + int Port=8080; + XSPWebSource websource=new XSPWebSource(IPAddress.Any,Port); + WebAppServer=new ApplicationServer(websource,physicalPath); + + var broker = new XSPRequestBroker (); + var host = new XSPApplicationHost (); + + host.RequestBroker = broker; + host.Server = WebAppServer; + broker.InitializeLifetimeService (); + host.InitializeLifetimeService (); + // ApplicationHost h = new XSPApplicationHost(); + + //"[[hostname:]port:]VPath:realpath" + string cmdLine=Port+":/:"+physicalPath; + WebAppServer.AddApplicationsFromCommandLine (cmdLine); + + WebAppServer.Broker = broker; + WebAppServer.AppHost = host; + // WebAppServer.AddApplicationsFromConfigFile (physicalPath+"/Web.config"); +// WebConfigurationFileMap map = new WebConfigurationFileMap (); +// map.VirtualDirectories.Add (dummyVirtualPath, new VirtualDirectoryMapping (physicalPath, true)); +// TODO why not? Configuration configuration = WebConfigurationManager.OpenMappedWebConfiguration (map, dummyVirtualPath); + +// string da = (string)config.AppSettings.Settings ["DefaultAvatar"].Value; +// MembershipSection s = config.GetSection ("system.web/membership") as MembershipSection; +// defaultMembershipProvider = s.DefaultProvider; + // ??? WebConfigurationManager.ConfigPath + Configuration cfg = WebConfigurationManager.OpenWebConfiguration (dummyVirtualPath); +// WebConfigurationManager.AppSettings.Clear (); +// WebConfigurationManager.ConnectionStrings.Clear (); +// var mbrssect = WebConfigurationManager.GetWebApplicationSection ("system.web/membership") as MembershipSection; +// +// mbrssect.Providers.Clear (); + var syswebcfg = WebConfigurationManager.GetWebApplicationSection ("system.web") as ConfigurationSection; + + WebAppServer.Start (true,2000); +// System.Threading.Thread.Sleep(30000); } [Test ()] public virtual void Register () { + accountController = new AccountController (); + ViewResult actionResult = accountController.Register ( new Yavsc.Model.RolesAndMembers.RegisterViewModel () { UserName = UserName, Email = Email, @@ -93,7 +135,11 @@ namespace Yavsc Assert.True (u.IsApproved); } - [TestFixtureTearDown()] + [Test()] + public virtual void Stop() { + WebAppServer.Stop(); + } + public virtual void Unregister() { ViewResult actionResult = diff --git a/TestAPI/TestAPI.csproj b/TestAPI/TestAPI.csproj index 8e601b4c..0668c673 100644 --- a/TestAPI/TestAPI.csproj +++ b/TestAPI/TestAPI.csproj @@ -58,11 +58,37 @@ + + + + + + + + ..\..\..\..\..\usr\lib\mono\4.5\Mono.WebServer2.dll + + + ..\..\..\..\..\usr\lib\mono\4.5\xsp4.exe + + + nunit + + + nunit + + + nunit + - + + + + + + @@ -74,8 +100,28 @@ {77044C92-D2F1-45BD-80DD-AA25B311B027} Web + + {C6E9E91B-97D3-48D9-8AA7-05356929E162} + NpgsqlBlogProvider + + + {821FF72D-9F4B-4A2C-B95C-7B965291F119} + NpgsqlContentProvider + + + {BBA7175D-7F92-4278-96FC-84C495A2B5A6} + NpgsqlMRPProviders + + + {90BF2234-7252-4CD5-B2A4-17501B19279B} + SalesCatalog + + + False + PreserveNewest + - \ No newline at end of file + diff --git a/TestAPI/TestAutomate.cs b/TestAPI/TestAutomate.cs index ea9a9efb..b83313a4 100644 --- a/TestAPI/TestAutomate.cs +++ b/TestAPI/TestAutomate.cs @@ -55,7 +55,9 @@ namespace TestAPI [Test] public void DoTheTest() { + // Establish context.Invoke (); + // Because of.Invoke (); should_be_in_state_0.Invoke (); should_not_be_in_state_1.Invoke (); diff --git a/TestAPI/Web.config b/TestAPI/test-domain-TestAPI.config similarity index 100% rename from TestAPI/Web.config rename to TestAPI/test-domain-TestAPI.config diff --git a/web/ApiControllers/BlogsController.cs b/web/ApiControllers/BlogsController.cs index 6da541b5..d987e85e 100644 --- a/web/ApiControllers/BlogsController.cs +++ b/web/ApiControllers/BlogsController.cs @@ -21,38 +21,38 @@ namespace Yavsc.ApiControllers /// public class BlogsController : YavscApiController { - private const string adminRoleName = "Admin"; - /// - /// Initialize the specified controllerContext. + /// Tag the specified postid and tag. /// - /// Controller context. - protected override void Initialize (System.Web.Http.Controllers.HttpControllerContext controllerContext) - { - base.Initialize (controllerContext); - if (!Roles.RoleExists (adminRoleName)) { - Roles.CreateRole (adminRoleName); + /// Postid. + /// Tag. + [Authorize, + AcceptVerbs ("POST")] + public void Tag (PostTag model) { + if (ModelState.IsValid) { + BlogManager.GetForEditing (model.PostId); + BlogManager.Tag (model.PostId, model.Tag); } } - - /// - /// Tag the specified postid and tag. + /// + /// Tags the specified pattern. /// - /// Postid. - /// Tag. - public void Tag (long postid,string tag) { - BlogManager.GetForEditing (postid); - BlogManager.Tag (postid, tag); + /// Pattern. + [ValidateAjaxAttribute] + public IEnumerable Tags(string pattern) + { + return new string[] { "Artistes", "Accueil", "Mentions juridique", "Admin", "Web" } ; } /// /// Untag the specified postid and tag. /// - /// Postid. + /// Postid. /// Tag. - public void Untag (long postid,string tag) { - BlogManager.GetForEditing (postid); - BlogManager.Untag (postid, tag); + [Authorize, ValidateAjaxAttribute, HttpPost] + public void Untag (long id, [FromBody] string tag) { + BlogManager.GetForEditing (id); + BlogManager.Untag (id, tag); } /// @@ -60,8 +60,8 @@ namespace Yavsc.ApiControllers /// /// User. /// Title. - [Authorize] - public void RemoveTitle(string user, string title) { + [Authorize, ValidateAjaxAttribute, HttpPost] + public void RemoveTitle(string user, string title) { if (Membership.GetUser ().UserName != user) if (!Roles.IsUserInRole("Admin")) throw new AuthorizationDenied (user); @@ -72,7 +72,8 @@ namespace Yavsc.ApiControllers /// Removes the tag. /// /// Tagid. - public void RemoveTag(long tagid) { + [Authorize, ValidateAjaxAttribute, HttpPost] + public void RemoveTag([FromBody] long tagid) { throw new NotImplementedException (); } @@ -96,7 +97,7 @@ namespace Yavsc.ApiControllers /// Posts the file. /// /// The file. - [Authorize,HttpPost] + [Authorize, HttpPost] public async Task PostFile(long id) { if (!(Request.Content.Headers.ContentType.MediaType=="multipart/form-data")) throw new HttpRequestException ("not a multipart/form-data request"); @@ -142,10 +143,10 @@ namespace Yavsc.ApiControllers /// Searchs the file. /// /// The file. - /// Postid. + /// Postid. /// Terms. - [Authorize,HttpGet] - public async Task SearchFile(long postid, string terms) { + [HttpGet] + public async Task SearchFile(long id, string terms) { throw new NotImplementedException (); } @@ -154,8 +155,8 @@ namespace Yavsc.ApiControllers /// /// Identifier. /// Photo. - [Authorize,HttpPost] - public void SetPhoto(long id, string photo) + [Authorize, HttpPost, ValidateAjaxAttribute] + public void SetPhoto(long id, [FromBody] string photo) { BlogManager.Provider.UpdatePostPhoto (id, photo); } @@ -164,6 +165,7 @@ namespace Yavsc.ApiControllers /// Import the specified id. /// /// Identifier. + [Authorize, HttpPost, ValidateAjaxAttribute] public async Task Import(long id) { if (!(Request.Content.Headers.ContentType.MediaType=="multipart/form-data")) throw new HttpRequestException ("not a multipart/form-data request"); diff --git a/web/App_Themes/style.css b/web/App_Themes/style.css index 0918f8dd..69da7604 100644 --- a/web/App_Themes/style.css +++ b/web/App_Themes/style.css @@ -7,24 +7,53 @@ body { padding: 0; margin: 0; } - +/* Start by setting display:none to make this hidden. + Then we position it in relation to the viewport window + with position:fixed. Width, height, top and left speak + for themselves. Background we set to 80% white with + our animation centered, and no-repeating */ +.modal { + display: none; + position: fixed; + z-index: 1000; + top: 0; + left: 0; + height: 100%; + width: 100%; + background: rgba( 255, 255, 255, .8 ) + url('http://i.stack.imgur.com/FhHRx.gif') + 50% 50% + no-repeat; +} + +/* When the body has the loading class, we turn + the scrollbar off with overflow:hidden */ +body.loading { + overflow: hidden; +} + +/* Anytime the body has the loading class, our + modal element will be visible */ +body.loading .modal { + display: block; +} .iconsmall { max-height: 1.3em; max-width: 1.3em; } .photo { width: 100%; } .blogbanner { float: left; top:0; } +.subtitle { font-size:small; font-style: italic; } header { padding: 0; margin: 0; - margin-top: 0; padding-top: 201px; - margin-bottom:2em; + padding-bottom:2em; display: block; - text-align: center; background: url("/images/totem-banner.xs.jpg") 0 0 no-repeat fixed; } header h1, header a { background-color: rgba(0,0,0,.5); +margin:0; padding:1em; } nav { @@ -34,12 +63,11 @@ nav { border-radius:1em; background: url("/images/live-concert-388160_1280.jpg") 50% 10em repeat fixed ; justify-content: space-around; - min-height:5em; } main { margin: 2em; - padding: 6em 2em 6em 2em; + padding: 2em; display: block; border-radius:1em; background: url("/images/musician-923526_1.nbb.jpg") 50% 20em repeat fixed ; @@ -54,29 +82,26 @@ footer { clear: both; font-size: smaller; justify-content: space-around; - } footer a { - border-radius:5px; - margin:.5em; + border-radius:1em; padding:1em; } legend { border-radius:5px; - margin:.5em; - padding:1.5em; + padding:.5em; background-color: rgba(0,0,32,.5); } #copyr { text-align: center; display: block; background-color: rgba(20,20,20,.8); } footer p { display:inline-block; } -footer img { max-height: 2em; vertical-align: middle; } +footer img { max-height: 3em; vertical-align: middle; } a img, h1 img, .menuitem img { max-height: 1em; vertical-align: middle; } #gspacer { background-color: rgba(20,20,20,.8); - border-radius:5px; - margin:.5em; padding:1em; display: inline-block } + border-radius:1em; + margin:1em; padding:1em; display: inline-block } fieldset { background-color: rgba(16,16,64,0.8); border-radius:5px; border: solid 1px #000060; @@ -85,7 +110,7 @@ fieldset { main video, main img { max-width:100%; max-height:75%; - padding: .5em; + padding: 1em; } aside { @@ -97,10 +122,9 @@ aside { .postpreview { display: inline-block; max-width: 40em; - padding: .5em; - margin: .5em; + padding: 1em; background-color: rgba(0,0,32,0.8); - border-radius:10px; + border-radius:1em; } .postpreview video, .postpreview img { max-width:100%; @@ -108,11 +132,10 @@ aside { } .post { display:block; - margin:1em; - padding:1em; + padding: 1em; background-color: rgba(0,0,32,0.8); color: #eee; - border-radius:10px; + border-radius:1em; } .hiddenpost { background-color: rgba(16,16,16,0.5); } .fullwidth { width: 100%; } @@ -129,24 +152,23 @@ textarea.fullwidth { min-height:10em; } .panel,.bshpanel, aside { background-color: rgba(20,20,20,.8); - border-radius: 5px; - margin: .5em; - padding: .5em; + border-radius: 1em; + padding: 1em; } .spanel { max-width: 24em; display: inline-block; - margin: .3em; + padding: .3em; } .xspanel { max-width:13em; display: inline-block; - margin:.2em; + padding:.2em; } .xxspanel { max-width:7em; display: inline-block; - margin:.1em; + padding:.1em; } .hint { display: inline; @@ -162,7 +184,7 @@ content: ")"; .usertitleref { - border-radius: 5px; + border-radius: 1em; background-color:rgba(0,0,32,0.6); font-family: 'Arial', cursive; padding: 1em; @@ -180,8 +202,7 @@ label { border: dashed rgb(020,20,256) 2px; } #notifications { - margin: 2em; - padding: 2em; + padding: 1em; } .notification { @@ -230,7 +251,6 @@ a { cursor: pointer; font-family: 'Arial', cursive; padding: 1em; - margin:1em; } input, select, textarea { @@ -299,22 +319,33 @@ input, select, textarea { .c3-alt { display:none; } @media all and (max-width: 640px) { +header { + padding-bottom:1em; + } + +header h1, header a , .actionlink, .menuitem, a { padding:.5em;} + nav { - margin: 1em; + margin: 1em; padding: 1em; - min-height:4em; background: url("/images/live-concert-388160_1280.s.jpg") 50% 10% repeat fixed ; } main { - margin: 1em; - padding: 4em 1em 4em 1em; + margin: 1em; + padding: 1em; background: url("/images/musician-923526_1.nbb.xs.jpg") 50% 20em repeat fixed ; } footer { - background: url("/images/drummer-652345_1280.xs.jpg") 50% 90% repeat fixed ; - padding: 1em; - margin: 1em; + background: url("/images/drummer-652345_1280.s.jpg") 50% 90% repeat fixed ; } + footer a { + border-radius:.5em; + margin:.5em; + padding:.5em; + } + #notifications { + padding: .5em; + } .menuitem { display: block; } @@ -326,7 +357,6 @@ input, select, textarea { padding:.3em; } .bshpanel { cursor:zoom-in; } - footer { clear:both; } .c2 { display:initial; } .c2-alt { display:none; } @@ -336,30 +366,30 @@ input, select, textarea { @media all and (max-width: 350px) { header { - padding: 0; - margin: 0; - margin-top: 0; padding-top: 101px; - margin-bottom:1em; + padding-bottom:1em; background: url("/images/totem-banner.xxs.jpg") 0 0 no-repeat fixed; } +header h1, header a { padding:.2em;} + nav { - margin: .5em; + margin: .5em; padding: .5em; - min-height:3em; background: url("/images/live-concert-388160_1280.xxs.jpg") 50% 10% repeat fixed ; } main { - margin: .5em; - padding: 3em .5em 3em .5em; + margin: .5em; + padding: .5em; background: url("/images/musician-923526_1.nbb.xxs.jpg") 50% 20em repeat fixed ; } footer { background: url("/images/drummer-652345_1280.xxs.jpg") 50% 90% repeat fixed ; - - margin: 0.5em; - padding: 0.5em; } + footer a { + border-radius:.2em; + margin:.2em; + padding:.2em; + } .c2 { display:none; } .c2-alt { display:initial; } } diff --git a/web/ChangeLog b/web/ChangeLog index 797a34bf..85517ec8 100644 --- a/web/ChangeLog +++ b/web/ChangeLog @@ -1,3 +1,29 @@ +2015-10-17 Paul Schneider + + * Web.csproj: + * Global.asax.cs: + * yavsc.js: + * App.master: + * style.css: + * Edit.aspx: + * Title.aspx: + * Index.aspx: + * YavscHelpers.cs: + * UserPost.aspx: + * UserPosts.aspx: + * PageLinks.ascx: + * TagControl.ascx: + * PostActions.ascx: + * HomeController.cs: + * AdminController.cs: + * BlogsController.cs: + * GoogleController.cs: + * Estimate.aspx: + * AccountController.cs: + * BlogsController.cs: + * knockout-jqAutocomplete.js: + * knockout-jqAutocomplete.min.js: + 2015-10-13 Paul Schneider * Index.aspx: diff --git a/web/Controllers/AccountController.cs b/web/Controllers/AccountController.cs index 1f763956..5ec92924 100644 --- a/web/Controllers/AccountController.cs +++ b/web/Controllers/AccountController.cs @@ -388,20 +388,20 @@ namespace Yavsc.Controllers { MembershipUser u = Membership.GetUser (id, false); if (u == null) { - ViewData ["Error"] = - string.Format ("Cet utilisateur n'existe pas ({0})", id); + YavscHelpers.Notify( ViewData, + string.Format ("Cet utilisateur n'existe pas ({0})", id)); } else if (u.ProviderUserKey.ToString () == key) { if (u.IsApproved) { - ViewData ["Message"] = - string.Format ("Votre compte ({0}) est déjà validé.", id); + YavscHelpers.Notify( ViewData, + string.Format ("Votre compte ({0}) est déjà validé.", id)); } else { u.IsApproved = true; Membership.UpdateUser (u); - ViewData ["Message"] = - string.Format ("La création de votre compte ({0}) est validée.", id); + YavscHelpers.Notify( ViewData, + string.Format ("La création de votre compte ({0}) est validée.", id)); } } else - ViewData ["Error"] = "La clé utilisée pour valider ce compte est incorrecte"; + YavscHelpers.Notify( ViewData, "La clé utilisée pour valider ce compte est incorrecte" ); return View (); } diff --git a/web/Controllers/AdminController.cs b/web/Controllers/AdminController.cs index f2cede23..297ff2ce 100644 --- a/web/Controllers/AdminController.cs +++ b/web/Controllers/AdminController.cs @@ -165,7 +165,7 @@ namespace Yavsc.Controllers ViewData ["usertoremove"] = username; if (submitbutton == "Supprimer") { Membership.DeleteUser (username); - YavscHelpers.Notice(ViewData, string.Format("utilisateur \"{0}\" supprimé",username)); + YavscHelpers.Notify(ViewData, string.Format("utilisateur \"{0}\" supprimé",username)); ViewData ["usertoremove"] = null; } return View (); @@ -240,7 +240,7 @@ namespace Yavsc.Controllers public ActionResult DoAddRole (string rolename) { Roles.CreateRole(rolename); - YavscHelpers.Notice(ViewData, LocalizedText.role_created+ " : "+rolename); + YavscHelpers.Notify(ViewData, LocalizedText.role_created+ " : "+rolename); return View (); } @@ -278,7 +278,7 @@ namespace Yavsc.Controllers ViewData ["useritems"] = users; if (ModelState.IsValid) { Roles.AddUserToRole (model.UserName, adminRoleName); - YavscHelpers.Notice(ViewData, model.UserName + " "+LocalizedText.was_added_to_the_role+" '" + adminRoleName + "'"); + YavscHelpers.Notify(ViewData, model.UserName + " "+LocalizedText.was_added_to_the_role+" '" + adminRoleName + "'"); } else { if (admins.Length > 0) { if (! admins.Contains (Membership.GetUser ().UserName)) { @@ -290,7 +290,7 @@ namespace Yavsc.Controllers // No admin, gives the Admin Role to the current user Roles.AddUserToRole (currentUser, adminRoleName); admins = new string[] { currentUser }; - YavscHelpers.Notice(ViewData, string.Format ( + YavscHelpers.Notify(ViewData, string.Format ( LocalizedText.was_added_to_the_empty_role, currentUser, adminRoleName)); } diff --git a/web/Controllers/BlogsController.cs b/web/Controllers/BlogsController.cs index ad688cdc..7037dc65 100644 --- a/web/Controllers/BlogsController.cs +++ b/web/Controllers/BlogsController.cs @@ -36,8 +36,11 @@ namespace Yavsc.Controllers /// Title. /// Page index. /// Page size. - public ActionResult Index (int pageIndex = 0, int pageSize = 10) + public ActionResult Index (string title, int pageIndex = 0, int pageSize = 10) { + if (title != null) + return Title (title, pageIndex, pageSize); + return BlogList (pageIndex, pageSize); } /// @@ -45,7 +48,7 @@ namespace Yavsc.Controllers /// /// The media. /// Identifier. - public ActionResult ChooseMedia(long id) + public ActionResult ChooseMedia(long postid) { return View (); } @@ -76,20 +79,20 @@ namespace Yavsc.Controllers /// Page size. /// [HttpGet] - public ActionResult Title (string id, int pageIndex = 0, int pageSize = 10) + public ActionResult Title (string title, int pageIndex = 0, int pageSize = 10) { int recordCount; MembershipUser u = Membership.GetUser (); string username = u == null ? null : u.UserName; FindBlogEntryFlags sf = FindBlogEntryFlags.MatchTitle; BlogEntryCollection c = - BlogManager.FindPost (username, id, sf, pageIndex, pageSize, out recordCount); - var utc = new UTBlogEntryCollection (id); + BlogManager.FindPost (username, title, sf, pageIndex, pageSize, out recordCount); + var utc = new UTBlogEntryCollection (title); utc.AddRange (c); ViewData ["RecordCount"] = recordCount; ViewData ["PageIndex"] = pageIndex; ViewData ["PageSize"] = pageSize; - return View (utc); + return View ("Title", utc); } /// @@ -100,27 +103,30 @@ namespace Yavsc.Controllers /// Page index. /// Page size. [HttpGet] - public ActionResult UserPosts (string id, int pageIndex = 0, int pageSize = 10) + public ActionResult UserPosts (string user, string title=null, int pageIndex = 0, int pageSize = 10) { + if (title != null) return UserPost (user, title, pageIndex, pageSize); int recordcount=0; MembershipUser u = Membership.GetUser (); FindBlogEntryFlags sf = FindBlogEntryFlags.MatchUserName; ViewData ["SiteName"] = sitename; - ViewData ["BlogUser"] = id; + ViewData ["BlogUser"] = user; string readersName = null; ViewData ["PageIndex"] = pageIndex; ViewData ["pageSize"] = pageSize; // displays invisible items when the logged user is also the author if (u != null) { - if (u.UserName == id || Roles.IsUserInRole ("Admin")) + if (u.UserName == user || Roles.IsUserInRole ("Admin")) sf |= FindBlogEntryFlags.MatchInvisible; readersName = u.UserName; + if (user == null) + user = u.UserName; } // find entries BlogEntryCollection c = - BlogManager.FindPost (readersName, id, sf, pageIndex, pageSize, out recordcount); + BlogManager.FindPost (readersName, user, sf, pageIndex, pageSize, out recordcount); // Get author's meta data - var pr = ProfileBase.Create (id); + var pr = ProfileBase.Create (user); if (pr != null) { Profile bupr = new Profile (pr); ViewData ["BlogUserProfile"] = bupr; @@ -130,7 +136,7 @@ namespace Yavsc.Controllers ViewData ["Avatar"] = bupr.avatar; } ViewData ["RecordCount"] = recordcount; - UUBlogEntryCollection uuc = new UUBlogEntryCollection (id, c); + UUBlogEntryCollection uuc = new UUBlogEntryCollection (user, c); return View ("UserPosts", uuc); } @@ -147,14 +153,14 @@ namespace Yavsc.Controllers } /// - /// Returns the post. + /// Gets the post. /// /// The post. - /// Identifier. - public ActionResult GetPost (long id) + /// Postid. + public ActionResult GetPost (long postid) { - ViewData ["id"] = id; - BlogEntry e = BlogManager.GetForReading (id); + ViewData ["id"] = postid; + BlogEntry e = BlogManager.GetForReading (postid); UUTBlogEntryCollection c = new UUTBlogEntryCollection (e.Author,e.Title); c.Add (e); ViewData ["user"] = c.Author; @@ -306,15 +312,15 @@ namespace Yavsc.Controllers /// /// Identifier. [Authorize] - public ActionResult Edit (long id) + public ActionResult Edit (long postid) { - BlogEntry e = BlogManager.GetForEditing (id); + BlogEntry e = BlogManager.GetForEditing (postid); string user = Membership.GetUser ().UserName; Profile pr = new Profile (ProfileBase.Create(e.Author)); ViewData ["BlogTitle"] = pr.BlogTitle; ViewData ["LOGIN"] = user; - ViewData ["Id"] = id; + ViewData ["Id"] = postid; // Populates the circles combo items if (e.AllowedCircles == null) @@ -356,21 +362,21 @@ namespace Yavsc.Controllers /// Return URL. /// If set to true confirm. [Authorize] - public ActionResult RemoveTitle (string id, string user, string returnUrl, bool confirm = false) + public ActionResult RemoveTitle (string user, string title, string returnUrl, bool confirm = false) { if (returnUrl == null) if (Request.UrlReferrer != null) returnUrl = Request.UrlReferrer.AbsoluteUri; ViewData ["returnUrl"] = returnUrl; ViewData ["Author"] = user; - ViewData ["Title"] = id; + ViewData ["Title"] = title; if (Membership.GetUser ().UserName != user) if (!Roles.IsUserInRole("Admin")) throw new AuthorizationDenied (user); if (!confirm) return View ("RemoveTitle"); - BlogManager.RemoveTitle (user, id); + BlogManager.RemoveTitle (user, title); if (returnUrl == null) RedirectToAction ("Index", new { user = user }); return Redirect (returnUrl); @@ -384,19 +390,19 @@ namespace Yavsc.Controllers /// Return URL. /// If set to true confirm. [Authorize] - public ActionResult RemovePost (long id, string returnUrl, bool confirm = false) + public ActionResult RemovePost (long postid, string returnUrl, bool confirm = false) { // ensures the access control - BlogEntry e = BlogManager.GetForEditing (id); + BlogEntry e = BlogManager.GetForEditing (postid); if (e == null) - return new HttpNotFoundResult ("post id "+id.ToString()); - ViewData ["id"] = id; + return new HttpNotFoundResult ("post id "+postid.ToString()); + ViewData ["id"] = postid; ViewData ["returnUrl"] = string.IsNullOrWhiteSpace(returnUrl)? Request.UrlReferrer.AbsoluteUri.ToString(): returnUrl; // TODO: cleaner way to disallow deletion if (!confirm) return View ("RemovePost",e); - BlogManager.RemovePost (id); + BlogManager.RemovePost (postid); if (string.IsNullOrWhiteSpace(returnUrl)) return RedirectToAction ("Index"); return Redirect (returnUrl); diff --git a/web/Controllers/GoogleController.cs b/web/Controllers/GoogleController.cs index b25824a3..1e4a1bac 100644 --- a/web/Controllers/GoogleController.cs +++ b/web/Controllers/GoogleController.cs @@ -106,7 +106,7 @@ namespace Yavsc.Controllers AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg); if (gat == null) { - YavscHelpers.Notice(ViewData, msg); + YavscHelpers.Notify(ViewData, msg); return View ("Auth"); } SaveToken (gat); @@ -143,7 +143,7 @@ namespace Yavsc.Controllers OAuth2 oa = new OAuth2 (AuthGRU); AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg); if (gat == null) { - YavscHelpers.Notice(ViewData, msg); + YavscHelpers.Notify(ViewData, msg); return View (); } string returnUrl = (string)Session ["returnUrl"]; diff --git a/web/Controllers/HomeController.cs b/web/Controllers/HomeController.cs index df42f267..f8548685 100644 --- a/web/Controllers/HomeController.cs +++ b/web/Controllers/HomeController.cs @@ -121,7 +121,7 @@ namespace Yavsc.Controllers using (System.Net.Mail.SmtpClient sc = new SmtpClient()) { sc.Send (msg); - YavscHelpers.Notice(ViewData, LocalizedText.Message_sent); + YavscHelpers.Notify(ViewData, LocalizedText.Message_sent); return View (new { email=email, reason="", body="" }); } } diff --git a/web/Global.asax.cs b/web/Global.asax.cs index 05aaf410..645be2b6 100644 --- a/web/Global.asax.cs +++ b/web/Global.asax.cs @@ -47,17 +47,33 @@ namespace Yavsc routes.IgnoreRoute ("favicon.png"); // favorite icon routes.IgnoreRoute ("robots.txt"); // for search engine robots routes.MapRoute ( - "View", - "v/{title}", + "Titles", + "t/{title}", new { controller = "Blogs", action = "Index", title=UrlParameter.Optional } ); routes.MapRoute ( "Blogs", - "b/{user}/{title}", + "b/{user}", + new { controller = "Blogs", + action = "UserPosts", + user="Paul Schneider" } + ); + + routes.MapRoute ( + "BlogByTitle", + "by/{user}/{title}/{id}", + new { controller = "Blogs", + action = "UserPosts", + user="Paul Schneider", + title=UrlParameter.Optional, + id=UrlParameter.Optional } + ); + routes.MapRoute ( + "BlogById", + "b/{action}/{postid}", new { controller = "Blogs", action = "Index", - user=UrlParameter.Optional, - title=UrlParameter.Optional } + postid=UrlParameter.Optional } ); /* routes.MapRoute ( "Artistes", diff --git a/web/Helpers/YavscHelpers.cs b/web/Helpers/YavscHelpers.cs index 5941034c..3bf9ee1d 100644 --- a/web/Helpers/YavscHelpers.cs +++ b/web/Helpers/YavscHelpers.cs @@ -13,6 +13,7 @@ using System.Web.UI; using System.Linq.Expressions; using System.Web.Profile; using System.Web.Script.Serialization; +using System.Web.Mvc; namespace Yavsc.Helpers { @@ -214,14 +215,22 @@ namespace Yavsc.Helpers return serializer.Serialize(obj); } /// - /// Notice the specified ViewData with message. + /// Notifies /// /// View data. /// Message. - public static void Notice (System.Web.Mvc.ViewDataDictionary ViewData, string message) { - if (ViewData ["Notifications"] == null) - ViewData ["Notifications"] = new List (); - (ViewData ["Notifications"] as List).Add (message.Replace("\'","\\\'")); + public static void Notify (this HtmlHelper helper, string message) { + Notify (helper.ViewData, message); + } + /// + /// Notify the specified viewData and message. + /// + /// View data. + /// Message. + public static void Notify(ViewDataDictionary viewData, string message) { + if (viewData ["Notifications"] == null) + viewData ["Notifications"] = new List (); + (viewData ["Notifications"] as List).Add (message.Replace("\'","\\\'")); } /// /// Files the list. @@ -279,6 +288,53 @@ namespace Yavsc.Helpers return new System.Web.Mvc.MvcHtmlString (str.ToString ()); } + /// + /// Renders the page links. + /// + /// The page links. + /// Helper. + /// Result count. + /// Page size. + /// Page index. + public static IHtmlString RenderPageLinks ( + this HtmlHelper helper, + int PageIndex, int PageSize, int ResultCount, + string args="?PageIndex={0}", + string pagesLabel="Pages: ", string singlePage="", + string none="néant" + ) + { + StringWriter strwr = new StringWriter (); + HtmlTextWriter writer = new HtmlTextWriter(strwr); + + if (ResultCount > 0 && ResultCount > PageSize ) { + int pageCount = ((ResultCount-1) / PageSize) + 1; + if ( pageCount > 1 ) { + writer.WriteEncodedText (pagesLabel); + for (int pi = (PageIndex < 5) ? 0 : PageIndex - 5; pi < pageCount && pi < PageIndex + 5; pi++) { + if (PageIndex == pi) + writer.RenderBeginTag ("b"); + else { + writer.AddAttribute (HtmlTextWriterAttribute.Href, + string.Format (args, pi)); + writer.RenderBeginTag ("a"); + } + writer.Write (pi + 1); + writer.RenderEndTag (); + writer.Write (" "); + } + } + else { + writer.Write (singlePage); + } + } + if (ResultCount == 0) { + writer.Write (none); + } + return new MvcHtmlString(strwr.ToString()); + } + + } } diff --git a/web/Models/App.master b/web/Models/App.master index fdeb027e..71a0c0ba 100644 --- a/web/Models/App.master +++ b/web/Models/App.master @@ -19,8 +19,9 @@ - - + @@ -29,34 +30,38 @@ var apiBaseUrl = '<%=Url.Content(Yavsc.WebApiConfig.UrlPrefixRelative)%>';

"> <%=ViewState["orgtitle"]%> - - -"><%= YavscHelpers.SiteName %> -

+- "><%= YavscHelpers.SiteName %> +
-<%if (ViewData ["Notifications"]!=null) { %> -<% } %> @@ -93,6 +98,6 @@ Yavsc.notice('<%=notice%>');
- + diff --git a/web/Scripts/knockout-jqAutocomplete.js b/web/Scripts/knockout-jqAutocomplete.js new file mode 100644 index 00000000..c7e56054 --- /dev/null +++ b/web/Scripts/knockout-jqAutocomplete.js @@ -0,0 +1,189 @@ +// knockout-jqAutocomplete 0.4.3 | (c) 2015 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license +;(function(factory) { + if (typeof define === "function" && define.amd) { + // AMD anonymous module + define(["knockout", "jquery", "jquery-ui/autocomplete"], factory); + } else { + // No module loader - put directly in global namespace + factory(window.ko, jQuery); + } +})(function(ko, $) { + var JqAuto = function() { + var self = this, + unwrap = ko.utils.unwrapObservable; //support older KO versions that did not have ko.unwrap + + //binding's init function + this.init = function(element, valueAccessor, allBindings, data, context) { + var existingSelect, existingChange, + options = unwrap(valueAccessor()), + config = {}, + filter = typeof options.filter === "function" ? options.filter : self.defaultFilter; + + //extend with global options + ko.utils.extend(config, self.options); + //override with options passed in binding + ko.utils.extend(config, options.options); + + //get source from a function (can be remote call) + if (typeof options.source === "function" && !ko.isObservable(options.source)) { + config.source = function(request, response) { + //provide a wrapper to the normal response callback + var callback = function(data) { + self.processOptions(valueAccessor, null, data, request, response); + }; + + //call the provided function for retrieving data + options.source.call(context.$data, request.term, callback); + }; + } + else { + //process local data + config.source = self.processOptions.bind(self, valueAccessor, filter, options.source); + } + + //save any passed in select/change calls + existingSelect = typeof config.select === "function" && config.select; + existingChange = typeof config.change === "function" && config.change; + + //handle updating the actual value + config.select = function(event, ui) { + if (ui.item && ui.item.actual) { + options.value(ui.item.actual); + + if (ko.isWriteableObservable(options.dataValue)) { + options.dataValue(ui.item.data); + } + } + + if (existingSelect) { + existingSelect.apply(this, arguments); + } + }; + + //user made a change without selecting a value from the list + config.change = function(event, ui) { + if (!ui.item || !ui.item.actual) { + options.value(event.target && event.target.value); + + if (ko.isWriteableObservable(options.dataValue)) { + options.dataValue(null); + } + } + + if (existingChange) { + existingChange.apply(this, arguments); + } + }; + + //initialize the widget + var widget = $(element).autocomplete(config).data("ui-autocomplete"); + + //render a template for the items + if (options.template) { + widget._renderItem = self.renderItem.bind(self, options.template, context); + } + + //destroy the widget if KO removes the element + ko.utils.domNodeDisposal.addDisposeCallback(element, function() { + if (widget && typeof widget.destroy === "function") { + widget.destroy(); + widget = null; + } + }); + }; + + //the binding's update function. keep value in sync with model + this.update = function(element, valueAccessor) { + var propNames, sources, + options = unwrap(valueAccessor()), + value = unwrap(options && options.value); + + if (!value && value !== 0) { + value = ""; + } + + // find the appropriate value for the input + sources = unwrap(options.source); + propNames = self.getPropertyNames(valueAccessor); + + // if there is local data, then try to determine the appropriate value for the input + if ($.isArray(sources) && propNames.value) { + value = ko.utils.arrayFirst(sources, function (opt) { + return opt[propNames.value] == value; + } + ) || value; + } + + if (propNames.input && value && typeof value === "object") { + element.value = value[propNames.input]; + } + else { + element.value = value; + } + }; + + //if dealing with local data, the default filtering function + this.defaultFilter = function(item, term) { + term = term && term.toLowerCase(); + return (item || item === 0) && ko.toJSON(item).toLowerCase().indexOf(term) > -1; + }; + + //filter/map options to be in a format that autocomplete requires + this.processOptions = function(valueAccessor, filter, data, request, response) { + var item, index, length, + items = unwrap(data) || [], + results = [], + props = this.getPropertyNames(valueAccessor); + + //filter/map items + for (index = 0, length = items.length; index < length; index++) { + item = items[index]; + + if (!filter || filter(item, request.term)) { + results.push({ + label: props.label ? item[props.label] : item.toString(), + value: props.input ? item[props.input] : item.toString(), + actual: props.value ? item[props.value] : item, + data: item + }); + } + } + + //call autocomplete callback to display list + response(results); + }; + + //if specified, use a template to render an item + this.renderItem = function(templateName, context, ul, item) { + var $li = $("
  • ").appendTo(ul), + itemContext = context.createChildContext(item.data); + + //apply the template binding + ko.applyBindingsToNode($li[0], { template: templateName }, itemContext); + + //clean up + $li.one("remove", ko.cleanNode.bind(ko, $li[0])); + + return $li; + }; + + //retrieve the property names to use for the label, input, and value + this.getPropertyNames = function(valueAccessor) { + var options = ko.toJS(valueAccessor()); + + return { + label: options.labelProp || options.valueProp, + input: options.inputProp || options.labelProp || options.valueProp, + value: options.valueProp + }; + }; + + //default global options passed into autocomplete widget + this.options = { + autoFocus: true, + delay: 50 + }; + }; + + ko.bindingHandlers.jqAuto = new JqAuto(); +}); diff --git a/web/Scripts/knockout-jqAutocomplete.min.js b/web/Scripts/knockout-jqAutocomplete.min.js new file mode 100644 index 00000000..00652e5d --- /dev/null +++ b/web/Scripts/knockout-jqAutocomplete.min.js @@ -0,0 +1,2 @@ +// knockout-jqAutocomplete 0.4.3 | (c) 2015 Ryan Niemeyer | http://www.opensource.org/licenses/mit-license +!function(a){"function"==typeof define&&define.amd?define(["knockout","jquery","jquery-ui/autocomplete"],a):a(window.ko,jQuery)}(function(a,b){var c=function(){var c=this,d=a.utils.unwrapObservable;this.init=function(e,f,g,h,i){var j,k,l=d(f()),m={},n="function"==typeof l.filter?l.filter:c.defaultFilter;a.utils.extend(m,c.options),a.utils.extend(m,l.options),m.source="function"!=typeof l.source||a.isObservable(l.source)?c.processOptions.bind(c,f,n,l.source):function(a,b){var d=function(d){c.processOptions(f,null,d,a,b)};l.source.call(i.$data,a.term,d)},j="function"==typeof m.select&&m.select,k="function"==typeof m.change&&m.change,m.select=function(b,c){c.item&&c.item.actual&&(l.value(c.item.actual),a.isWriteableObservable(l.dataValue)&&l.dataValue(c.item.data)),j&&j.apply(this,arguments)},m.change=function(b,c){c.item&&c.item.actual||(l.value(b.target&&b.target.value),a.isWriteableObservable(l.dataValue)&&l.dataValue(null)),k&&k.apply(this,arguments)};var o=b(e).autocomplete(m).data("ui-autocomplete");l.template&&(o._renderItem=c.renderItem.bind(c,l.template,i)),a.utils.domNodeDisposal.addDisposeCallback(e,function(){o&&"function"==typeof o.destroy&&(o.destroy(),o=null)})},this.update=function(e,f){var g,h,i=d(f()),j=d(i&&i.value);j||0===j||(j=""),h=d(i.source),g=c.getPropertyNames(f),b.isArray(h)&&g.value&&(j=a.utils.arrayFirst(h,function(a){return a[g.value]==j})||j),e.value=g.input&&j&&"object"==typeof j?j[g.input]:j},this.defaultFilter=function(b,c){return c=c&&c.toLowerCase(),(b||0===b)&&a.toJSON(b).toLowerCase().indexOf(c)>-1},this.processOptions=function(a,b,c,e,f){var g,h,i,j=d(c)||[],k=[],l=this.getPropertyNames(a);for(h=0,i=j.length;i>h;h++)g=j[h],(!b||b(g,e.term))&&k.push({label:l.label?g[l.label]:g.toString(),value:l.input?g[l.input]:g.toString(),actual:l.value?g[l.value]:g,data:g});f(k)},this.renderItem=function(c,d,e,f){var g=b("
  • ").appendTo(e),h=d.createChildContext(f.data);return a.applyBindingsToNode(g[0],{template:c},h),g.one("remove",a.cleanNode.bind(a,g[0])),g},this.getPropertyNames=function(b){var c=a.toJS(b());return{label:c.labelProp||c.valueProp,input:c.inputProp||c.labelProp||c.valueProp,value:c.valueProp}},this.options={autoFocus:!0,delay:50}};a.bindingHandlers.jqAuto=new c}); \ No newline at end of file diff --git a/web/Scripts/yavsc.js b/web/Scripts/yavsc.js index 49d73fb6..5d4bde2f 100644 --- a/web/Scripts/yavsc.js +++ b/web/Scripts/yavsc.js @@ -1,6 +1,13 @@ var Yavsc = (function(apiBaseUrl){ var self = {}; +function dumpprops(obj) { +var str = ""; +for(var k in obj) + if (obj.hasOwnProperty(k)) + str += k + " = " + obj[k] + "\n"; + return (str); } + self.apiBaseUrl = (apiBaseUrl || '/api'); self.showHide = function () { @@ -33,8 +40,11 @@ self.notice = function (msg, msgok) { self.onAjaxBadInput = function (data) { + if (!data) { Yavsc.notice('no data'); return; } + if (!data.responseJSON) { Yavsc.notice('no json data:'+data); return; } + if (!Array.isArray(data.responseJSON)) { Yavsc.notice('Bad Input: '+data.responseJSON); return; } $.each(data.responseJSON, function (key, value) { - var errspanid = "Err_cr_" + value.key.replace("model.",""); + var errspanid = "Err_" + value.key; var errspan = document.getElementById(errspanid); if (errspan==null) alert('enoent '+errspanid); @@ -47,9 +57,24 @@ self.notice = function (msg, msgok) { self.onAjaxError = function (xhr, ajaxOptions, thrownError) { if (xhr.status!=400) Yavsc.notice(xhr.status+" : "+xhr.responseText); - else Yavsc.notice(false); }; return self; })(); +$(document).ready(function(){ + var $window = $(window); + $(window).scroll(function() { + var $ns = $('#notifications'); + if ($ns.has('*').length>0) { + if ($window.scrollTop()>375) { + $ns.css('position','fixed'); + $ns.css('z-index',2); + $ns.css('top',0); + } + else { + $ns.css('position','static'); + $ns.css('z-index',1); + }} + }); +}); diff --git a/web/Views/Blogs/Edit.aspx b/web/Views/Blogs/Edit.aspx index 11e9b1b3..2dc2562a 100644 --- a/web/Views/Blogs/Edit.aspx +++ b/web/Views/Blogs/Edit.aspx @@ -25,25 +25,19 @@
    +<% } %> +<% } %> diff --git a/web/Views/Blogs/Title.aspx b/web/Views/Blogs/Title.aspx index a4447f21..63bdd4b5 100644 --- a/web/Views/Blogs/Title.aspx +++ b/web/Views/Blogs/Title.aspx @@ -6,8 +6,8 @@

    -<%=Html.ActionLink(Model.Title, "Title", new{id=Model.Title}, null)%> -- "><%= YavscHelpers.SiteName %> +<%=Html.ActionLink(Model.Title, "Title", new{title=Model.Title}, null)%> +- "><%= YavscHelpers.SiteName %>

    diff --git a/web/Views/Blogs/UserPost.aspx b/web/Views/Blogs/UserPost.aspx index 5e9c07b5..605c43b8 100644 --- a/web/Views/Blogs/UserPost.aspx +++ b/web/Views/Blogs/UserPost.aspx @@ -30,7 +30,8 @@ <% string username = Membership.GetUser()==null ? null : Membership.GetUser().UserName; %> <% foreach (var c in (Comment[]) BlogManager.GetComments(be.Id)) { %> -
    " alt="<%=c.From%>"/> +
    +" alt="<%=c.From%>"/> <%= Html.Markdown(c.CommentText) %> <% if (Model.Author == username || c.From == username ) { %> <%= Html.ActionLink("Supprimer","RemoveComment", new { cmtid = c.Id } , new { @class="actionlink" })%> diff --git a/web/Views/Blogs/UserPosts.aspx b/web/Views/Blogs/UserPosts.aspx index 14dd3774..8cc1c06e 100644 --- a/web/Views/Blogs/UserPosts.aspx +++ b/web/Views/Blogs/UserPosts.aspx @@ -7,25 +7,26 @@ <% if (!string.IsNullOrEmpty((string)ViewData["Avatar"])) { %> -" id="avatar"> +" id="avatar"> " /> <% } %>

    -"> +"> <%=Html.Encode(ViewData["BlogTitle"])%> -- "><%= YavscHelpers.SiteName %> +- "><%= YavscHelpers.SiteName %>

    <% foreach (BlogEntry e in this.Model) { %>
    -

    <%= Html.ActionLink(e.Title,"UserPost", new { user=e.Author, title=e.Title, id = e.Id }, new { @class = "usertitleref" }) %>

    +

    " class="usertitleref"> +<%=Html.Markdown(e.Title)%>

    <% bool truncated = false; %> <%= Html.MarkdownToHtmlIntro(out truncated, e.Content,"/bfiles/"+e.Id+"/") %> <% if (truncated) { %> -"> +"> Html.Translate("ReadMore") <% } %> <%= Html.Partial("PostActions",e)%> diff --git a/web/Views/FrontOffice/Estimate.aspx b/web/Views/FrontOffice/Estimate.aspx index d850b336..db578a8c 100644 --- a/web/Views/FrontOffice/Estimate.aspx +++ b/web/Views/FrontOffice/Estimate.aspx @@ -3,9 +3,6 @@ @@ -352,6 +349,9 @@ function addRow(){ $("#wr_Count").val(1); $("#wr_UnitaryCost").val(0); }); + + $("#tbwrts").stupidtable(); + }); diff --git a/web/Web.csproj b/web/Web.csproj index fa00ffd3..38c87979 100644 --- a/web/Web.csproj +++ b/web/Web.csproj @@ -142,7 +142,6 @@ - @@ -190,7 +189,6 @@ - @@ -432,7 +430,10 @@ - + + + + diff --git a/yavscModel/Blogs/BasePost.cs b/yavscModel/Blogs/BasePost.cs index dd718750..2fc487dc 100644 --- a/yavscModel/Blogs/BasePost.cs +++ b/yavscModel/Blogs/BasePost.cs @@ -30,6 +30,8 @@ using System.ComponentModel.DataAnnotations; namespace Yavsc.Model.Blogs { + + /// /// Base post. /// @@ -52,6 +54,9 @@ namespace Yavsc.Model.Blogs id = value; } } + + + /// /// The posted. /// @@ -125,13 +130,21 @@ namespace Yavsc.Model.Blogs } } + /// + /// Gets or sets the photo. + /// + /// The photo. + public string Photo { + get; + set; + } + /// /// Gets or sets a value indicating whether this is visible. /// /// true if visible; otherwise, false. public bool Visible { get; set ; } - } } diff --git a/yavscModel/Blogs/BlogEntry.cs b/yavscModel/Blogs/BlogEntry.cs index aa2597a9..e46809e0 100644 --- a/yavscModel/Blogs/BlogEntry.cs +++ b/yavscModel/Blogs/BlogEntry.cs @@ -12,16 +12,20 @@ namespace Yavsc.Model.Blogs ///
    public class BlogEntry : BasePost { + /// - /// Gets or sets the photo. + /// Gets or sets the circles allowed to read this ticket. + /// An empty collection specifies a public post. /// - /// The photo. - public string Photo { - get; - set; - } - + /// The circles. + [Display(Name="Cercles autorisés")] + public long[] AllowedCircles { get; set; } + /// + /// Gets or sets the tags. + /// + /// The tags. + public string [] Tags { get; set ; } string content; @@ -40,21 +44,6 @@ namespace Yavsc.Model.Blogs } } - /// - /// Gets or sets the circles allowed to read this ticket. - /// An empty collection specifies a public post. - /// - /// The circles. - [Display(Name="Cercles autorisés")] - public long[] AllowedCircles { get; set; } - - /// - /// Gets or sets the tags. - /// - /// The tags. - public string [] Tags { get; set ; } - - } } diff --git a/yavscModel/Blogs/BlogEntryCollection.cs b/yavscModel/Blogs/BlogEntryCollection.cs index 86180ce2..1e0bd7ec 100644 --- a/yavscModel/Blogs/BlogEntryCollection.cs +++ b/yavscModel/Blogs/BlogEntryCollection.cs @@ -122,7 +122,11 @@ namespace Yavsc.Model.Blogs orderby be.Posted descending group new PostInfoByTitle { Author=be.Author, Id=be.Id, - Posted=be.Posted, Modified=be.Modified, Intro = MarkdownHelper.MarkdownIntro(be.Content, out truncated) } + Posted=be.Posted, Modified=be.Modified, + Intro = MarkdownHelper.MarkdownIntro(be.Content, out truncated), + Visible = be.Visible, + Photo = be.Photo + } by be.Title into titlegroup select titlegroup; @@ -137,8 +141,15 @@ namespace Yavsc.Model.Blogs return from be in this orderby be.Posted descending group - new PostInfoByUser { Title=be.Title, Id=be.Id, - Posted=be.Posted, Modified=be.Modified, Intro = MarkdownHelper.MarkdownIntro(be.Content, out truncated) } + new PostInfoByUser { + Title=be.Title, + Id=be.Id, + Posted=be.Posted, + Modified=be.Modified, + Intro = MarkdownHelper.MarkdownIntro(be.Content, out truncated) , + Photo = be.Photo, + Visible = be.Visible + } by be.Author into usergroup select usergroup; diff --git a/yavscModel/Blogs/PostTag.cs b/yavscModel/Blogs/PostTag.cs new file mode 100644 index 00000000..869aa196 --- /dev/null +++ b/yavscModel/Blogs/PostTag.cs @@ -0,0 +1,45 @@ +// +// PostTag.cs +// +// Author: +// Paul Schneider +// +// Copyright (c) 2015 GNU GPL +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see . + +using System; +using System.Configuration; +using System.Collections.Generic; +using Yavsc.Model.Blogs; +using System.Linq; +using Yavsc.Model.Circles; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; + +namespace Yavsc.Model.Blogs +{ + + public class PostTag { + public long PostId { get; set; } + + [StringLength(512)] + [RegularExpression(@"^[a-zA-Z0-9 ]+$",ErrorMessage = "Un tag n'est composé que de lettres et de chiffres, les espaces" + + "sont autorisés")] + [Required(ErrorMessage = "S'il vous plait, saisissez nom de tag")] + public string Tag { get; set; } + + } + +} diff --git a/yavscModel/ChangeLog b/yavscModel/ChangeLog index 2993a61f..b96318a8 100644 --- a/yavscModel/ChangeLog +++ b/yavscModel/ChangeLog @@ -1,3 +1,16 @@ +2015-10-17 Paul Schneider + + * PostTag.cs: + * BasePost.cs: + * YavscModel.csproj: + * BlogEntry.cs: + * LocalizedText.resx: + * Automate.cs: + * LocalizedText.fr.resx: + * LocalizedText.Designer.cs: + * BlogEntryCollection.cs: + * LocalizedText.fr.Designer.cs: + 2015-10-13 Paul Schneider * BasePost.cs: refactoring: diff --git a/yavscModel/LocalizedText.Designer.cs b/yavscModel/LocalizedText.Designer.cs index 9c240813..ec6dd646 100644 --- a/yavscModel/LocalizedText.Designer.cs +++ b/yavscModel/LocalizedText.Designer.cs @@ -46,165 +46,177 @@ namespace Yavsc.Model { } } - public static string was_added_to_the_empty_role { + public static string EventWebPage { get { - return ResourceManager.GetString("was_added_to_the_empty_role", resourceCulture); + return ResourceManager.GetString("EventWebPage", resourceCulture); } } - public static string Bill_edition { + public static string ProviderId { get { - return ResourceManager.GetString("Bill_edition", resourceCulture); + return ResourceManager.GetString("ProviderId", resourceCulture); } } - public static string Tex_version { + public static string Pdf_version { get { - return ResourceManager.GetString("Tex_version", resourceCulture); + return ResourceManager.GetString("Pdf_version", resourceCulture); } } - public static string Message_sent { + public static string Circles { get { - return ResourceManager.GetString("Message_sent", resourceCulture); + return ResourceManager.GetString("Circles", resourceCulture); } } - public static string Count { + public static string DuplicateEmail { get { - return ResourceManager.GetString("Count", resourceCulture); + return ResourceManager.GetString("DuplicateEmail", resourceCulture); } } - public static string Create { + public static string Preview { get { - return ResourceManager.GetString("Create", resourceCulture); + return ResourceManager.GetString("Preview", resourceCulture); } } - public static string Description { + public static string DisplayName { get { - return ResourceManager.GetString("Description", resourceCulture); + return ResourceManager.GetString("DisplayName", resourceCulture); } } - public static string Profile_edition { + public static string none { get { - return ResourceManager.GetString("Profile_edition", resourceCulture); + return ResourceManager.GetString("none", resourceCulture); } } - public static string Title { + public static string ProviderName { get { - return ResourceManager.GetString("Title", resourceCulture); + return ResourceManager.GetString("ProviderName", resourceCulture); } } - public static string My_Estimates { + public static string Not_Approuved { get { - return ResourceManager.GetString("My_Estimates", resourceCulture); + return ResourceManager.GetString("Not_Approuved", resourceCulture); } } - public static string Google_error { + public static string User_name { get { - return ResourceManager.GetString("Google_error", resourceCulture); + return ResourceManager.GetString("User_name", resourceCulture); } } - public static string StartDate { + public static string Estimate_not_found { get { - return ResourceManager.GetString("StartDate", resourceCulture); + return ResourceManager.GetString("Estimate_not_found", resourceCulture); } } - public static string no_content { + public static string was_added_to_the_empty_role { get { - return ResourceManager.GetString("no_content", resourceCulture); + return ResourceManager.GetString("was_added_to_the_empty_role", resourceCulture); } } - public static string DuplicateEmail { + public static string Members { get { - return ResourceManager.GetString("DuplicateEmail", resourceCulture); + return ResourceManager.GetString("Members", resourceCulture); } } - public static string Ciffer { + public static string Google_calendar { get { - return ResourceManager.GetString("Ciffer", resourceCulture); + return ResourceManager.GetString("Google_calendar", resourceCulture); } } - public static string Modify { + public static string Welcome { get { - return ResourceManager.GetString("Modify", resourceCulture); + return ResourceManager.GetString("Welcome", resourceCulture); } } - public static string MaxDate { + public static string Private_circle { get { - return ResourceManager.GetString("MaxDate", resourceCulture); + return ResourceManager.GetString("Private_circle", resourceCulture); } } - public static string younotadmin { + public static string ImportException { get { - return ResourceManager.GetString("younotadmin", resourceCulture); + return ResourceManager.GetString("ImportException", resourceCulture); } } - public static string ProviderName { + public static string access_denied { get { - return ResourceManager.GetString("ProviderName", resourceCulture); + return ResourceManager.GetString("access_denied", resourceCulture); } } - public static string Date_search { + public static string Ciffer { get { - return ResourceManager.GetString("Date_search", resourceCulture); + return ResourceManager.GetString("Ciffer", resourceCulture); } } - public static string Members { + public static string Create { get { - return ResourceManager.GetString("Members", resourceCulture); + return ResourceManager.GetString("Create", resourceCulture); } } - public static string ImportException { + public static string Submit { get { - return ResourceManager.GetString("ImportException", resourceCulture); + return ResourceManager.GetString("Submit", resourceCulture); } } - public static string Preview { + public static string ImgLocator { get { - return ResourceManager.GetString("Preview", resourceCulture); + return ResourceManager.GetString("ImgLocator", resourceCulture); } } - public static string Register { + public static string entries { get { - return ResourceManager.GetString("Register", resourceCulture); + return ResourceManager.GetString("entries", resourceCulture); } } - public static string View_source { + public static string Description { get { - return ResourceManager.GetString("View_source", resourceCulture); + return ResourceManager.GetString("Description", resourceCulture); } } - public static string Hide_source { + public static string Google_error { get { - return ResourceManager.GetString("Hide_source", resourceCulture); + return ResourceManager.GetString("Google_error", resourceCulture); } } - public static string access_denied { + public static string Comment { get { - return ResourceManager.GetString("access_denied", resourceCulture); + return ResourceManager.GetString("Comment", resourceCulture); + } + } + + public static string Tex_version { + get { + return ResourceManager.GetString("Tex_version", resourceCulture); + } + } + + public static string Item_added_to_basket { + get { + return ResourceManager.GetString("Item_added_to_basket", resourceCulture); } } @@ -220,207 +232,219 @@ namespace Yavsc.Model { } } - public static string EndDate { + public static string Hide { get { - return ResourceManager.GetString("EndDate", resourceCulture); + return ResourceManager.GetString("Hide", resourceCulture); } } - public static string Google_calendar { + public static string Register { get { - return ResourceManager.GetString("Google_calendar", resourceCulture); + return ResourceManager.GetString("Register", resourceCulture); } } - public static string Consultant { + public static string younotadmin { get { - return ResourceManager.GetString("Consultant", resourceCulture); + return ResourceManager.GetString("younotadmin", resourceCulture); } } - public static string EventWebPage { + public static string Location { get { - return ResourceManager.GetString("EventWebPage", resourceCulture); + return ResourceManager.GetString("Location", resourceCulture); } } - public static string ImgLocator { + public static string New_Tag { get { - return ResourceManager.GetString("ImgLocator", resourceCulture); + return ResourceManager.GetString("New_Tag", resourceCulture); } } - public static string DoTag { + public static string Modify { get { - return ResourceManager.GetString("DoTag", resourceCulture); + return ResourceManager.GetString("Modify", resourceCulture); } } - public static string Not_Approuved { + public static string Remove { get { - return ResourceManager.GetString("Not_Approuved", resourceCulture); + return ResourceManager.GetString("Remove", resourceCulture); } } - public static string Private_circle { + public static string Title { get { - return ResourceManager.GetString("Private_circle", resourceCulture); + return ResourceManager.GetString("Title", resourceCulture); } } - public static string DocTemplateException { + public static string Tag_name { get { - return ResourceManager.GetString("DocTemplateException", resourceCulture); + return ResourceManager.GetString("Tag_name", resourceCulture); } } - public static string Unitary_cost { + public static string Message_sent { get { - return ResourceManager.GetString("Unitary_cost", resourceCulture); + return ResourceManager.GetString("Message_sent", resourceCulture); } } - public static string Circles { + public static string Offline { get { - return ResourceManager.GetString("Circles", resourceCulture); + return ResourceManager.GetString("Offline", resourceCulture); } } - public static string Location { + public static string Bill_edition { get { - return ResourceManager.GetString("Location", resourceCulture); + return ResourceManager.GetString("Bill_edition", resourceCulture); } } - public static string Remember_me { + public static string InternalServerError { get { - return ResourceManager.GetString("Remember_me", resourceCulture); + return ResourceManager.GetString("InternalServerError", resourceCulture); } } - public static string Remove { + public static string MaxDate { get { - return ResourceManager.GetString("Remove", resourceCulture); + return ResourceManager.GetString("MaxDate", resourceCulture); } } - public static string none { + public static string Count { get { - return ResourceManager.GetString("none", resourceCulture); + return ResourceManager.GetString("Count", resourceCulture); } } - public static string User_List { + public static string Edit { get { - return ResourceManager.GetString("User_List", resourceCulture); + return ResourceManager.GetString("Edit", resourceCulture); } } - public static string Estimate_not_found { + public static string Date_search { get { - return ResourceManager.GetString("Estimate_not_found", resourceCulture); + return ResourceManager.GetString("Date_search", resourceCulture); } } - public static string ProviderId { + public static string View_source { get { - return ResourceManager.GetString("ProviderId", resourceCulture); + return ResourceManager.GetString("View_source", resourceCulture); } } - public static string Welcome { + public static string role_created { get { - return ResourceManager.GetString("Welcome", resourceCulture); + return ResourceManager.GetString("role_created", resourceCulture); } } - public static string Online { + public static string ReadMore { get { - return ResourceManager.GetString("Online", resourceCulture); + return ResourceManager.GetString("ReadMore", resourceCulture); } } - public static string Home { + public static string EndDate { get { - return ResourceManager.GetString("Home", resourceCulture); + return ResourceManager.GetString("EndDate", resourceCulture); } } - public static string Offline { + public static string MinDate { get { - return ResourceManager.GetString("Offline", resourceCulture); + return ResourceManager.GetString("MinDate", resourceCulture); } } - public static string MinDate { + public static string User_List { get { - return ResourceManager.GetString("MinDate", resourceCulture); + return ResourceManager.GetString("User_List", resourceCulture); } } - public static string Comment { + public static string Remember_me { get { - return ResourceManager.GetString("Comment", resourceCulture); + return ResourceManager.GetString("Remember_me", resourceCulture); } } - public static string User_name { + public static string Home { get { - return ResourceManager.GetString("User_name", resourceCulture); + return ResourceManager.GetString("Home", resourceCulture); } } - public static string DisplayName { + public static string Consultant { get { - return ResourceManager.GetString("DisplayName", resourceCulture); + return ResourceManager.GetString("Consultant", resourceCulture); } } - public static string Pdf_version { + public static string was_added_to_the_role { get { - return ResourceManager.GetString("Pdf_version", resourceCulture); + return ResourceManager.GetString("was_added_to_the_role", resourceCulture); } } - public static string ReadMore { + public static string DoTag { get { - return ResourceManager.GetString("ReadMore", resourceCulture); + return ResourceManager.GetString("DoTag", resourceCulture); } } - public static string Item_added_to_basket { + public static string DocTemplateException { get { - return ResourceManager.GetString("Item_added_to_basket", resourceCulture); + return ResourceManager.GetString("DocTemplateException", resourceCulture); } } - public static string role_created { + public static string no_content { get { - return ResourceManager.GetString("role_created", resourceCulture); + return ResourceManager.GetString("no_content", resourceCulture); } } - public static string Edit { + public static string Unitary_cost { get { - return ResourceManager.GetString("Edit", resourceCulture); + return ResourceManager.GetString("Unitary_cost", resourceCulture); } } - public static string InternalServerError { + public static string Online { get { - return ResourceManager.GetString("InternalServerError", resourceCulture); + return ResourceManager.GetString("Online", resourceCulture); } } - public static string entries { + public static string StartDate { get { - return ResourceManager.GetString("entries", resourceCulture); + return ResourceManager.GetString("StartDate", resourceCulture); } } - public static string was_added_to_the_role { + public static string Hide_source { get { - return ResourceManager.GetString("was_added_to_the_role", resourceCulture); + return ResourceManager.GetString("Hide_source", resourceCulture); + } + } + + public static string Profile_edition { + get { + return ResourceManager.GetString("Profile_edition", resourceCulture); + } + } + + public static string My_Estimates { + get { + return ResourceManager.GetString("My_Estimates", resourceCulture); } } } diff --git a/yavscModel/LocalizedText.fr.Designer.cs b/yavscModel/LocalizedText.fr.Designer.cs index eee58c06..e5af1b95 100644 --- a/yavscModel/LocalizedText.fr.Designer.cs +++ b/yavscModel/LocalizedText.fr.Designer.cs @@ -148,9 +148,9 @@ namespace Yavsc.Model { } } - public static string younotadmin { + public static string New_Tag { get { - return ResourceManager.GetString("younotadmin", resourceCulture); + return ResourceManager.GetString("New_Tag", resourceCulture); } } @@ -250,6 +250,12 @@ namespace Yavsc.Model { } } + public static string Submit { + get { + return ResourceManager.GetString("Submit", resourceCulture); + } + } + public static string Not_Approuved { get { return ResourceManager.GetString("Not Approuved", resourceCulture); @@ -286,6 +292,12 @@ namespace Yavsc.Model { } } + public static string Tag_name { + get { + return ResourceManager.GetString("Tag_name", resourceCulture); + } + } + public static string Remove { get { return ResourceManager.GetString("Remove", resourceCulture); @@ -298,6 +310,12 @@ namespace Yavsc.Model { } } + public static string Hide { + get { + return ResourceManager.GetString("Hide", resourceCulture); + } + } + public static string Estimate_not_found { get { return ResourceManager.GetString("Estimate_not_found", resourceCulture); @@ -370,6 +388,12 @@ namespace Yavsc.Model { } } + public static string younotadmin { + get { + return ResourceManager.GetString("younotadmin", resourceCulture); + } + } + public static string Item_added_to_basket { get { return ResourceManager.GetString("Item_added_to_basket", resourceCulture); diff --git a/yavscModel/LocalizedText.fr.resx b/yavscModel/LocalizedText.fr.resx index 58a84b29..7fbb8551 100644 --- a/yavscModel/LocalizedText.fr.resx +++ b/yavscModel/LocalizedText.fr.resx @@ -35,6 +35,7 @@ Erreur Google : {0} Cacher le texte source du billet Accueil + Cacher URI de l'image Exception à l'import Erreur serveur interne @@ -46,6 +47,7 @@ Date minimale du rendez-vous Modifier Mes estimations + Nouveau Tag aucun(e) Non approuvé pas de contenu @@ -63,8 +65,10 @@ Supprimer Rôle créé Date de démarrage + Soumettre Version LaTeX Titre + Nom du tag Coût unitaire Liste des utilisateurs Nom d'utilisateur diff --git a/yavscModel/LocalizedText.resx b/yavscModel/LocalizedText.resx index 1703e832..001024eb 100644 --- a/yavscModel/LocalizedText.resx +++ b/yavscModel/LocalizedText.resx @@ -33,6 +33,7 @@ Estimate not found Event Web page Home + Hide Hide the bill source text entries Google calendar @@ -48,6 +49,7 @@ Minimal date for the rendez-vous Modify My estimates + New Tag none no content Not Approuved @@ -66,8 +68,10 @@ Remove role created Start date + Submit LaTeX version Title + Tag name Unitary_cost User List User name diff --git a/yavscModel/WorkFlow/Automate.cs b/yavscModel/WorkFlow/Automate.cs index 703b8f20..2b0a77c5 100644 --- a/yavscModel/WorkFlow/Automate.cs +++ b/yavscModel/WorkFlow/Automate.cs @@ -31,7 +31,7 @@ namespace Yavsc.Model.WorkFlow /// /// Initializes a new instance of the Automate class. /// - public Automate () + public Automate () { } private Dictionary> transitions = diff --git a/yavscModel/YavscModel.csproj b/yavscModel/YavscModel.csproj index a89fb2f9..0b691e62 100644 --- a/yavscModel/YavscModel.csproj +++ b/yavscModel/YavscModel.csproj @@ -173,6 +173,7 @@ +