From 9b2ec3ac533201cdb262c6a4d649c2c906880784 Mon Sep 17 00:00:00 2001 From: David Radcliffe Date: Sat, 18 Jul 2015 22:31:33 -0400 Subject: [PATCH 01/74] add Dyn provider --- builtin/bins/provider-dyn/main.go | 12 ++ builtin/bins/provider-dyn/main_test.go | 1 + builtin/providers/dyn/config.go | 28 +++ builtin/providers/dyn/provider.go | 50 +++++ builtin/providers/dyn/provider_test.go | 47 +++++ builtin/providers/dyn/resource_dyn_record.go | 177 +++++++++++++++++ .../providers/dyn/resource_dyn_record_test.go | 178 ++++++++++++++++++ 7 files changed, 493 insertions(+) create mode 100644 builtin/bins/provider-dyn/main.go create mode 100644 builtin/bins/provider-dyn/main_test.go create mode 100644 builtin/providers/dyn/config.go create mode 100644 builtin/providers/dyn/provider.go create mode 100644 builtin/providers/dyn/provider_test.go create mode 100644 builtin/providers/dyn/resource_dyn_record.go create mode 100644 builtin/providers/dyn/resource_dyn_record_test.go diff --git a/builtin/bins/provider-dyn/main.go b/builtin/bins/provider-dyn/main.go new file mode 100644 index 000000000..22809f46a --- /dev/null +++ b/builtin/bins/provider-dyn/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/hashicorp/terraform/builtin/providers/dyn" + "github.com/hashicorp/terraform/plugin" +) + +func main() { + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: dyn.Provider, + }) +} diff --git a/builtin/bins/provider-dyn/main_test.go b/builtin/bins/provider-dyn/main_test.go new file mode 100644 index 000000000..06ab7d0f9 --- /dev/null +++ b/builtin/bins/provider-dyn/main_test.go @@ -0,0 +1 @@ +package main diff --git a/builtin/providers/dyn/config.go b/builtin/providers/dyn/config.go new file mode 100644 index 000000000..091c929d9 --- /dev/null +++ b/builtin/providers/dyn/config.go @@ -0,0 +1,28 @@ +package dyn + +import ( + "fmt" + "log" + + "github.com/nesv/go-dynect/dynect" +) + +type Config struct { + CustomerName string + Username string + Password string +} + +// Client() returns a new client for accessing dyn. +func (c *Config) Client() (*dynect.ConvenientClient, error) { + client := dynect.NewConvenientClient(c.CustomerName) + err := client.Login(c.Username, c.Password) + + if err != nil { + return nil, fmt.Errorf("Error setting up Dyn client: %s", err) + } + + log.Printf("[INFO] Dyn client configured for customer: %s, user: %s", c.CustomerName, c.Username) + + return client, nil +} diff --git a/builtin/providers/dyn/provider.go b/builtin/providers/dyn/provider.go new file mode 100644 index 000000000..c591745ae --- /dev/null +++ b/builtin/providers/dyn/provider.go @@ -0,0 +1,50 @@ +package dyn + +import ( + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +// Provider returns a terraform.ResourceProvider. +func Provider() terraform.ResourceProvider { + return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "customer_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("DYN_CUSTOMER_NAME", nil), + Description: "A Dyn customer name.", + }, + + "username": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("DYN_USERNAME", nil), + Description: "A Dyn username.", + }, + + "password": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("DYN_PASSWORD", nil), + Description: "The Dyn password.", + }, + }, + + ResourcesMap: map[string]*schema.Resource{ + "dyn_record": resourceDynRecord(), + }, + + ConfigureFunc: providerConfigure, + } +} + +func providerConfigure(d *schema.ResourceData) (interface{}, error) { + config := Config{ + CustomerName: d.Get("customer_name").(string), + Username: d.Get("username").(string), + Password: d.Get("password").(string), + } + + return config.Client() +} diff --git a/builtin/providers/dyn/provider_test.go b/builtin/providers/dyn/provider_test.go new file mode 100644 index 000000000..da148ff2f --- /dev/null +++ b/builtin/providers/dyn/provider_test.go @@ -0,0 +1,47 @@ +package dyn + +import ( + "os" + "testing" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +var testAccProviders map[string]terraform.ResourceProvider +var testAccProvider *schema.Provider + +func init() { + testAccProvider = Provider().(*schema.Provider) + testAccProviders = map[string]terraform.ResourceProvider{ + "dyn": testAccProvider, + } +} + +func TestProvider(t *testing.T) { + if err := Provider().(*schema.Provider).InternalValidate(); err != nil { + t.Fatalf("err: %s", err) + } +} + +func TestProvider_impl(t *testing.T) { + var _ terraform.ResourceProvider = Provider() +} + +func testAccPreCheck(t *testing.T) { + if v := os.Getenv("DYN_CUSTOMER_NAME"); v == "" { + t.Fatal("DYN_CUSTOMER_NAME must be set for acceptance tests") + } + + if v := os.Getenv("DYN_USERNAME"); v == "" { + t.Fatal("DYN_USERNAME must be set for acceptance tests") + } + + if v := os.Getenv("DYN_PASSWORD"); v == "" { + t.Fatal("DYN_PASSWORD must be set for acceptance tests.") + } + + if v := os.Getenv("DYN_ZONE"); v == "" { + t.Fatal("DYN_ZONE must be set for acceptance tests. The domain is used to ` and destroy record against.") + } +} diff --git a/builtin/providers/dyn/resource_dyn_record.go b/builtin/providers/dyn/resource_dyn_record.go new file mode 100644 index 000000000..24c2977d5 --- /dev/null +++ b/builtin/providers/dyn/resource_dyn_record.go @@ -0,0 +1,177 @@ +package dyn + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/nesv/go-dynect/dynect" +) + +func resourceDynRecord() *schema.Resource { + return &schema.Resource{ + Create: resourceDynRecordCreate, + Read: resourceDynRecordRead, + Update: resourceDynRecordUpdate, + Delete: resourceDynRecordDelete, + + Schema: map[string]*schema.Schema{ + "zone": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "fqdn": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + + "type": &schema.Schema{ + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "value": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + + "ttl": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "0", // 0 means use zone default + }, + }, + } +} + +func resourceDynRecordCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*dynect.ConvenientClient) + + record := &dynect.Record{ + Name: d.Get("name").(string), + Zone: d.Get("zone").(string), + Type: d.Get("type").(string), + TTL: d.Get("ttl").(string), + Value: d.Get("value").(string), + } + log.Printf("[DEBUG] Dyn record create configuration: %#v", record) + + // create the record + err := client.CreateRecord(record) + if err != nil { + return fmt.Errorf("Failed to create Dyn record: %s", err) + } + + // publish the zone + err = client.PublishZone(record.Zone) + if err != nil { + return fmt.Errorf("Failed to publish Dyn zone: %s", err) + } + + // get the record ID + err = client.GetRecordID(record) + if err != nil { + return fmt.Errorf("%s", err) + } + d.SetId(record.ID) + + return resourceDynRecordRead(d, meta) +} + +func resourceDynRecordRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*dynect.ConvenientClient) + + record := &dynect.Record{ + ID: d.Id(), + Name: d.Get("name").(string), + Zone: d.Get("zone").(string), + TTL: d.Get("ttl").(string), + FQDN: d.Get("fqdn").(string), + Type: d.Get("type").(string), + } + + err := client.GetRecord(record) + if err != nil { + return fmt.Errorf("Couldn't find Dyn record: %s", err) + } + + d.Set("zone", record.Zone) + d.Set("fqdn", record.FQDN) + d.Set("name", record.Name) + d.Set("type", record.Type) + d.Set("ttl", record.TTL) + d.Set("value", record.Value) + + return nil +} + +func resourceDynRecordUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*dynect.ConvenientClient) + + record := &dynect.Record{ + Name: d.Get("name").(string), + Zone: d.Get("zone").(string), + TTL: d.Get("ttl").(string), + Type: d.Get("type").(string), + Value: d.Get("value").(string), + } + log.Printf("[DEBUG] Dyn record update configuration: %#v", record) + + // update the record + err := client.UpdateRecord(record) + if err != nil { + return fmt.Errorf("Failed to update Dyn record: %s", err) + } + + // publish the zone + err = client.PublishZone(record.Zone) + if err != nil { + return fmt.Errorf("Failed to publish Dyn zone: %s", err) + } + + // get the record ID + err = client.GetRecordID(record) + if err != nil { + return fmt.Errorf("%s", err) + } + d.SetId(record.ID) + + return resourceDynRecordRead(d, meta) +} + +func resourceDynRecordDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*dynect.ConvenientClient) + + record := &dynect.Record{ + ID: d.Id(), + Name: d.Get("name").(string), + Zone: d.Get("zone").(string), + FQDN: d.Get("fqdn").(string), + Type: d.Get("type").(string), + } + + log.Printf("[INFO] Deleting Dyn record: %s, %s", record.FQDN, record.ID) + + // delete the record + err := client.DeleteRecord(record) + if err != nil { + return fmt.Errorf("Failed to delete Dyn record: %s", err) + } + + // publish the zone + err = client.PublishZone(record.Zone) + if err != nil { + return fmt.Errorf("Failed to publish Dyn zone: %s", err) + } + + return nil +} diff --git a/builtin/providers/dyn/resource_dyn_record_test.go b/builtin/providers/dyn/resource_dyn_record_test.go new file mode 100644 index 000000000..ccb0ccd98 --- /dev/null +++ b/builtin/providers/dyn/resource_dyn_record_test.go @@ -0,0 +1,178 @@ +package dyn + +import ( + "fmt" + "os" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/nesv/go-dynect/dynect" +) + +func TestAccDynRecord_Basic(t *testing.T) { + var record dynect.Record + zone := os.Getenv("DYN_ZONE") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDynRecordDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: fmt.Sprintf(testAccCheckDynRecordConfig_basic, zone), + Check: resource.ComposeTestCheckFunc( + testAccCheckDynRecordExists("dyn_record.foobar", &record), + testAccCheckDynRecordAttributes(&record), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "name", "terraform"), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "zone", zone), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "value", "192.168.0.10"), + ), + }, + }, + }) +} + +func TestAccDynRecord_Updated(t *testing.T) { + var record dynect.Record + zone := os.Getenv("DYN_ZONE") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDynRecordDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: fmt.Sprintf(testAccCheckDynRecordConfig_basic, zone), + Check: resource.ComposeTestCheckFunc( + testAccCheckDynRecordExists("dyn_record.foobar", &record), + testAccCheckDynRecordAttributes(&record), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "name", "terraform"), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "zone", zone), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "value", "192.168.0.10"), + ), + }, + resource.TestStep{ + Config: fmt.Sprintf(testAccCheckDynRecordConfig_new_value, zone), + Check: resource.ComposeTestCheckFunc( + testAccCheckDynRecordExists("dyn_record.foobar", &record), + testAccCheckDynRecordAttributesUpdated(&record), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "name", "terraform"), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "zone", zone), + resource.TestCheckResourceAttr( + "dyn_record.foobar", "value", "192.168.0.11"), + ), + }, + }, + }) +} + +func testAccCheckDynRecordDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*dynect.ConvenientClient) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "dyn_record" { + continue + } + + foundRecord := &dynect.Record{ + Zone: rs.Primary.Attributes["zone"], + ID: rs.Primary.ID, + FQDN: rs.Primary.Attributes["fqdn"], + Type: rs.Primary.Attributes["type"], + } + + err := client.GetRecord(foundRecord) + + if err != nil { + return fmt.Errorf("Record still exists") + } + } + + return nil +} + +func testAccCheckDynRecordAttributes(record *dynect.Record) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if record.Value != "192.168.0.10" { + return fmt.Errorf("Bad value: %s", record.Value) + } + + return nil + } +} + +func testAccCheckDynRecordAttributesUpdated(record *dynect.Record) resource.TestCheckFunc { + return func(s *terraform.State) error { + + if record.Value != "192.168.0.11" { + return fmt.Errorf("Bad value: %s", record.Value) + } + + return nil + } +} + +func testAccCheckDynRecordExists(n string, record *dynect.Record) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + + if !ok { + return fmt.Errorf("Not found: %s", n) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Record ID is set") + } + + client := testAccProvider.Meta().(*dynect.ConvenientClient) + + foundRecord := &dynect.Record{ + Zone: rs.Primary.Attributes["zone"], + ID: rs.Primary.ID, + FQDN: rs.Primary.Attributes["fqdn"], + Type: rs.Primary.Attributes["type"], + } + + err := client.GetRecord(foundRecord) + + if err != nil { + return err + } + + if foundRecord.ID != rs.Primary.ID { + return fmt.Errorf("Record not found") + } + + *record = *foundRecord + + return nil + } +} + +const testAccCheckDynRecordConfig_basic = ` +resource "dyn_record" "foobar" { + zone = "%s" + name = "terraform" + value = "192.168.0.10" + type = "A" + ttl = 3600 +}` + +const testAccCheckDynRecordConfig_new_value = ` +resource "dyn_record" "foobar" { + zone = "%s" + name = "terraform" + value = "192.168.0.11" + type = "A" + ttl = 3600 +}` From 76dcc6659710d2b4de58645a324c0a7f115a09fb Mon Sep 17 00:00:00 2001 From: David Radcliffe Date: Tue, 21 Jul 2015 20:43:20 -0400 Subject: [PATCH 02/74] Dyn provider docs --- .../docs/providers/dyn/index.html.markdown | 39 ++++++++++++++++++ .../docs/providers/dyn/r/record.html.markdown | 41 +++++++++++++++++++ website/source/layouts/dyn.erb | 24 +++++++++++ 3 files changed, 104 insertions(+) create mode 100644 website/source/docs/providers/dyn/index.html.markdown create mode 100644 website/source/docs/providers/dyn/r/record.html.markdown create mode 100644 website/source/layouts/dyn.erb diff --git a/website/source/docs/providers/dyn/index.html.markdown b/website/source/docs/providers/dyn/index.html.markdown new file mode 100644 index 000000000..700bb0087 --- /dev/null +++ b/website/source/docs/providers/dyn/index.html.markdown @@ -0,0 +1,39 @@ +--- +layout: "dyn" +page_title: "Provider: Dyn" +sidebar_current: "docs-dyn-index" +description: |- + The Dyn provider is used to interact with the resources supported by Dyn. The provider needs to be configured with the proper credentials before it can be used. +--- + +# Dyn Provider + +The Dyn provider is used to interact with the +resources supported by Dyn. The provider needs to be configured +with the proper credentials before it can be used. + +Use the navigation to the left to read about the available resources. + +## Example Usage + +``` +# Configure the Dyn provider +provider "dyn" { + customer_name = "${var.dyn_customer_name}" + username = "${var.dyn_username}" + password = "${var.dyn_password}" +} + +# Create a record +resource "dyn_record" "www" { + ... +} +``` + +## Argument Reference + +The following arguments are supported: + +* `customer_name` - (Required) The Dyn customer name. It must be provided, but it can also be sourced from the `DYN_CUSTOMER_NAME` environment variable. +* `username` - (Required) The Dyn username. It must be provided, but it can also be sourced from the `DYN_USERNAME` environment variable. +* `password` - (Required) The Dyn password. It must be provided, but it can also be sourced from the `DYN_PASSWORD` environment variable. diff --git a/website/source/docs/providers/dyn/r/record.html.markdown b/website/source/docs/providers/dyn/r/record.html.markdown new file mode 100644 index 000000000..6094c27de --- /dev/null +++ b/website/source/docs/providers/dyn/r/record.html.markdown @@ -0,0 +1,41 @@ +--- +layout: "dyn" +page_title: "Dyn: dyn_record" +sidebar_current: "docs-dyn-resource-record" +description: |- + Provides a Dyn DNS record resource. +--- + +# dyn\_record + +Provides a Dyn DNS record resource. + +## Example Usage + +``` +# Add a record to the domain +resource "dyn_record" "foobar" { + zone = "${var.dyn_zone}" + name = "terraform" + value = "192.168.0.11" + type = "A" + ttl = 3600 +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name of the record. +* `type` - (Required) The type of the record. +* `value` - (Required) The value of the record. +* `zone` - (Required) The DNS zone to add the record to. +* `ttl` - (Optional) The TTL of the record. Default uses the zone default. + +## Attributes Reference + +The following attributes are exported: + +* `id` - The record ID. +* `fqdn` - The FQDN of the record, built from the `name` and the `zone`. diff --git a/website/source/layouts/dyn.erb b/website/source/layouts/dyn.erb new file mode 100644 index 000000000..ee66e7270 --- /dev/null +++ b/website/source/layouts/dyn.erb @@ -0,0 +1,24 @@ +<% wrap_layout :inner do %> + <% content_for :sidebar do %> + + <% end %> + + <%= yield %> +<% end %> From f5267dfa4477f14975b124710cbc696796950857 Mon Sep 17 00:00:00 2001 From: Patrick Gray Date: Tue, 15 Sep 2015 01:00:22 -0400 Subject: [PATCH 03/74] add support for group name and path changes with group update function --- .../providers/aws/resource_aws_iam_group.go | 35 +++++++++++++++---- .../aws/resource_aws_iam_group_test.go | 13 +++++++ 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/builtin/providers/aws/resource_aws_iam_group.go b/builtin/providers/aws/resource_aws_iam_group.go index 45defaaaf..c34137663 100644 --- a/builtin/providers/aws/resource_aws_iam_group.go +++ b/builtin/providers/aws/resource_aws_iam_group.go @@ -14,8 +14,7 @@ func resourceAwsIamGroup() *schema.Resource { return &schema.Resource{ Create: resourceAwsIamGroupCreate, Read: resourceAwsIamGroupRead, - // TODO - //Update: resourceAwsIamGroupUpdate, + Update: resourceAwsIamGroupUpdate, Delete: resourceAwsIamGroupDelete, Schema: map[string]*schema.Schema{ @@ -30,13 +29,11 @@ func resourceAwsIamGroup() *schema.Resource { "name": &schema.Schema{ Type: schema.TypeString, Required: true, - ForceNew: true, }, "path": &schema.Schema{ Type: schema.TypeString, Optional: true, Default: "/", - ForceNew: true, }, }, } @@ -45,9 +42,10 @@ func resourceAwsIamGroup() *schema.Resource { func resourceAwsIamGroupCreate(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn name := d.Get("name").(string) + path := d.Get("path").(string) request := &iam.CreateGroupInput{ - Path: aws.String(d.Get("path").(string)), + Path: aws.String(path), GroupName: aws.String(name), } @@ -60,9 +58,10 @@ func resourceAwsIamGroupCreate(d *schema.ResourceData, meta interface{}) error { func resourceAwsIamGroupRead(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn + name := d.Get("name").(string) request := &iam.GetGroupInput{ - GroupName: aws.String(d.Id()), + GroupName: aws.String(name), } getResp, err := iamconn.GetGroup(request) @@ -93,6 +92,30 @@ func resourceAwsIamGroupReadResult(d *schema.ResourceData, group *iam.Group) err return nil } +func resourceAwsIamGroupUpdate(d *schema.ResourceData, meta interface{}) error { + if d.HasChange("name") || d.HasChange("path") { + iamconn := meta.(*AWSClient).iamconn + on, nn := d.GetChange("name") + op, np := d.GetChange("path") + fmt.Println(on, nn, op, np) + request := &iam.UpdateGroupInput{ + GroupName: aws.String(on.(string)), + NewGroupName: aws.String(nn.(string)), + NewPath: aws.String(np.(string)), + } + _, err := iamconn.UpdateGroup(request) + if err != nil { + if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { + d.SetId("") + return nil + } + return fmt.Errorf("Error updating IAM Group %s: %s", d.Id(), err) + } + return resourceAwsIamGroupRead(d, meta) + } + return nil +} + func resourceAwsIamGroupDelete(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn diff --git a/builtin/providers/aws/resource_aws_iam_group_test.go b/builtin/providers/aws/resource_aws_iam_group_test.go index 67a72733a..c36a938b6 100644 --- a/builtin/providers/aws/resource_aws_iam_group_test.go +++ b/builtin/providers/aws/resource_aws_iam_group_test.go @@ -26,6 +26,13 @@ func TestAccAWSIAMGroup_basic(t *testing.T) { testAccCheckAWSGroupAttributes(&conf), ), }, + resource.TestStep{ + Config: testAccAWSGroupConfig2, + Check: resource.ComposeTestCheckFunc( + testAccCheckAWSGroupExists("aws_iam_group.group", &conf), + testAccCheckAWSGroupAttributes(&conf), + ), + }, }, }) } @@ -105,3 +112,9 @@ resource "aws_iam_group" "group" { path = "/" } ` +const testAccAWSGroupConfig2 = ` +resource "aws_iam_group" "group" { + name = "test-group2" + path = "/funnypath/" +} +` From 83e6d8b60ce58f71dce0c0dc60f468fc63551973 Mon Sep 17 00:00:00 2001 From: David Radcliffe Date: Wed, 2 Sep 2015 13:51:36 -0400 Subject: [PATCH 04/74] add Mutex so that we only do one Dyn operation at a time (extra thanks to @daveadams) --- builtin/providers/dyn/resource_dyn_record.go | 21 +++++++ .../providers/dyn/resource_dyn_record_test.go | 61 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/builtin/providers/dyn/resource_dyn_record.go b/builtin/providers/dyn/resource_dyn_record.go index 24c2977d5..7f7b66fd5 100644 --- a/builtin/providers/dyn/resource_dyn_record.go +++ b/builtin/providers/dyn/resource_dyn_record.go @@ -3,11 +3,14 @@ package dyn import ( "fmt" "log" + "sync" "github.com/hashicorp/terraform/helper/schema" "github.com/nesv/go-dynect/dynect" ) +var mutex = &sync.Mutex{} + func resourceDynRecord() *schema.Resource { return &schema.Resource{ Create: resourceDynRecordCreate, @@ -54,6 +57,8 @@ func resourceDynRecord() *schema.Resource { } func resourceDynRecordCreate(d *schema.ResourceData, meta interface{}) error { + mutex.Lock() + client := meta.(*dynect.ConvenientClient) record := &dynect.Record{ @@ -68,26 +73,33 @@ func resourceDynRecordCreate(d *schema.ResourceData, meta interface{}) error { // create the record err := client.CreateRecord(record) if err != nil { + mutex.Unlock() return fmt.Errorf("Failed to create Dyn record: %s", err) } // publish the zone err = client.PublishZone(record.Zone) if err != nil { + mutex.Unlock() return fmt.Errorf("Failed to publish Dyn zone: %s", err) } // get the record ID err = client.GetRecordID(record) if err != nil { + mutex.Unlock() return fmt.Errorf("%s", err) } d.SetId(record.ID) + mutex.Unlock() return resourceDynRecordRead(d, meta) } func resourceDynRecordRead(d *schema.ResourceData, meta interface{}) error { + mutex.Lock() + defer mutex.Unlock() + client := meta.(*dynect.ConvenientClient) record := &dynect.Record{ @@ -115,6 +127,8 @@ func resourceDynRecordRead(d *schema.ResourceData, meta interface{}) error { } func resourceDynRecordUpdate(d *schema.ResourceData, meta interface{}) error { + mutex.Lock() + client := meta.(*dynect.ConvenientClient) record := &dynect.Record{ @@ -129,26 +143,33 @@ func resourceDynRecordUpdate(d *schema.ResourceData, meta interface{}) error { // update the record err := client.UpdateRecord(record) if err != nil { + mutex.Unlock() return fmt.Errorf("Failed to update Dyn record: %s", err) } // publish the zone err = client.PublishZone(record.Zone) if err != nil { + mutex.Unlock() return fmt.Errorf("Failed to publish Dyn zone: %s", err) } // get the record ID err = client.GetRecordID(record) if err != nil { + mutex.Unlock() return fmt.Errorf("%s", err) } d.SetId(record.ID) + mutex.Unlock() return resourceDynRecordRead(d, meta) } func resourceDynRecordDelete(d *schema.ResourceData, meta interface{}) error { + mutex.Lock() + defer mutex.Unlock() + client := meta.(*dynect.ConvenientClient) record := &dynect.Record{ diff --git a/builtin/providers/dyn/resource_dyn_record_test.go b/builtin/providers/dyn/resource_dyn_record_test.go index ccb0ccd98..e23367283 100644 --- a/builtin/providers/dyn/resource_dyn_record_test.go +++ b/builtin/providers/dyn/resource_dyn_record_test.go @@ -75,6 +75,44 @@ func TestAccDynRecord_Updated(t *testing.T) { }) } +func TestAccDynRecord_Multiple(t *testing.T) { + var record dynect.Record + zone := os.Getenv("DYN_ZONE") + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckDynRecordDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: fmt.Sprintf(testAccCheckDynRecordConfig_multiple, zone, zone, zone), + Check: resource.ComposeTestCheckFunc( + testAccCheckDynRecordExists("dyn_record.foobar1", &record), + testAccCheckDynRecordAttributes(&record), + resource.TestCheckResourceAttr( + "dyn_record.foobar1", "name", "terraform1"), + resource.TestCheckResourceAttr( + "dyn_record.foobar1", "zone", zone), + resource.TestCheckResourceAttr( + "dyn_record.foobar1", "value", "192.168.0.10"), + resource.TestCheckResourceAttr( + "dyn_record.foobar2", "name", "terraform2"), + resource.TestCheckResourceAttr( + "dyn_record.foobar2", "zone", zone), + resource.TestCheckResourceAttr( + "dyn_record.foobar2", "value", "192.168.1.10"), + resource.TestCheckResourceAttr( + "dyn_record.foobar3", "name", "terraform3"), + resource.TestCheckResourceAttr( + "dyn_record.foobar3", "zone", zone), + resource.TestCheckResourceAttr( + "dyn_record.foobar3", "value", "192.168.2.10"), + ), + }, + }, + }) +} + func testAccCheckDynRecordDestroy(s *terraform.State) error { client := testAccProvider.Meta().(*dynect.ConvenientClient) @@ -176,3 +214,26 @@ resource "dyn_record" "foobar" { type = "A" ttl = 3600 }` + +const testAccCheckDynRecordConfig_multiple = ` +resource "dyn_record" "foobar1" { + zone = "%s" + name = "terraform1" + value = "192.168.0.10" + type = "A" + ttl = 3600 +} +resource "dyn_record" "foobar2" { + zone = "%s" + name = "terraform2" + value = "192.168.1.10" + type = "A" + ttl = 3600 +} +resource "dyn_record" "foobar3" { + zone = "%s" + name = "terraform3" + value = "192.168.2.10" + type = "A" + ttl = 3600 +}` From 9ab559645868071fc2149b6087e7b34c4abafd31 Mon Sep 17 00:00:00 2001 From: Patrick Gray Date: Sun, 4 Oct 2015 21:28:28 -0400 Subject: [PATCH 05/74] will not swallow error on aws iam group update if we get NoSuchEntity error --- builtin/providers/aws/resource_aws_iam_group.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/builtin/providers/aws/resource_aws_iam_group.go b/builtin/providers/aws/resource_aws_iam_group.go index c34137663..73a91b52e 100644 --- a/builtin/providers/aws/resource_aws_iam_group.go +++ b/builtin/providers/aws/resource_aws_iam_group.go @@ -105,10 +105,6 @@ func resourceAwsIamGroupUpdate(d *schema.ResourceData, meta interface{}) error { } _, err := iamconn.UpdateGroup(request) if err != nil { - if iamerr, ok := err.(awserr.Error); ok && iamerr.Code() == "NoSuchEntity" { - d.SetId("") - return nil - } return fmt.Errorf("Error updating IAM Group %s: %s", d.Id(), err) } return resourceAwsIamGroupRead(d, meta) From 6a2d3eaa6b59e3350456ce40cbc39a1b5fb549e7 Mon Sep 17 00:00:00 2001 From: Patrick Gray Date: Sat, 31 Oct 2015 10:52:12 -0400 Subject: [PATCH 06/74] remove unneeded print function --- builtin/providers/aws/resource_aws_iam_group.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builtin/providers/aws/resource_aws_iam_group.go b/builtin/providers/aws/resource_aws_iam_group.go index 73a91b52e..8e2938823 100644 --- a/builtin/providers/aws/resource_aws_iam_group.go +++ b/builtin/providers/aws/resource_aws_iam_group.go @@ -97,7 +97,7 @@ func resourceAwsIamGroupUpdate(d *schema.ResourceData, meta interface{}) error { iamconn := meta.(*AWSClient).iamconn on, nn := d.GetChange("name") op, np := d.GetChange("path") - fmt.Println(on, nn, op, np) + request := &iam.UpdateGroupInput{ GroupName: aws.String(on.(string)), NewGroupName: aws.String(nn.(string)), From 8fcc13adbc2f72b4051299822692e41199c917b0 Mon Sep 17 00:00:00 2001 From: Patrick Gray Date: Sat, 31 Oct 2015 12:04:54 -0400 Subject: [PATCH 07/74] update aws_iam_group tests to check proper paths and name --- .../providers/aws/resource_aws_iam_group_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/builtin/providers/aws/resource_aws_iam_group_test.go b/builtin/providers/aws/resource_aws_iam_group_test.go index c36a938b6..977889bd6 100644 --- a/builtin/providers/aws/resource_aws_iam_group_test.go +++ b/builtin/providers/aws/resource_aws_iam_group_test.go @@ -23,14 +23,14 @@ func TestAccAWSIAMGroup_basic(t *testing.T) { Config: testAccAWSGroupConfig, Check: resource.ComposeTestCheckFunc( testAccCheckAWSGroupExists("aws_iam_group.group", &conf), - testAccCheckAWSGroupAttributes(&conf), + testAccCheckAWSGroupAttributes(&conf, "test-group", "/"), ), }, resource.TestStep{ Config: testAccAWSGroupConfig2, Check: resource.ComposeTestCheckFunc( testAccCheckAWSGroupExists("aws_iam_group.group", &conf), - testAccCheckAWSGroupAttributes(&conf), + testAccCheckAWSGroupAttributes(&conf, "test-group2", "/funnypath/"), ), }, }, @@ -92,14 +92,14 @@ func testAccCheckAWSGroupExists(n string, res *iam.GetGroupOutput) resource.Test } } -func testAccCheckAWSGroupAttributes(group *iam.GetGroupOutput) resource.TestCheckFunc { +func testAccCheckAWSGroupAttributes(group *iam.GetGroupOutput, name string, path string) resource.TestCheckFunc { return func(s *terraform.State) error { - if *group.Group.GroupName != "test-group" { - return fmt.Errorf("Bad name: %s", *group.Group.GroupName) + if *group.Group.GroupName != name { + return fmt.Errorf("Bad name: %s when %s was expected", *group.Group.GroupName, name) } - if *group.Group.Path != "/" { - return fmt.Errorf("Bad path: %s", *group.Group.Path) + if *group.Group.Path != path { + return fmt.Errorf("Bad path: %s when %s was expected", *group.Group.Path, path) } return nil From 39cbc5616173916739b2bb5ef2c56bda802b71e0 Mon Sep 17 00:00:00 2001 From: captainill Date: Fri, 6 Nov 2015 12:35:24 -0800 Subject: [PATCH 08/74] in progress header redesign --- website/Gemfile.lock | 3 - website/source/assets/javascripts/app/Init.js | 6 + .../source/assets/javascripts/app/Sidebar.js | 50 +++ .../source/assets/javascripts/application.js | 1 + website/source/assets/stylesheets/_fonts.scss | 1 + .../source/assets/stylesheets/_header.scss | 402 ++---------------- .../source/assets/stylesheets/_sidebar.scss | 23 + .../source/assets/stylesheets/_utilities.scss | 16 - .../assets/stylesheets/application.scss | 12 +- .../hashicorp-shared/_hashicorp-header.scss | 166 ++++++++ .../hashicorp-shared/_hashicorp-sidebar.scss | 293 +++++++++++++ .../hashicorp-shared/_hashicorp-utility.scss | 86 ++++ .../hashicorp-shared/_project-utility.scss | 17 + website/source/layouts/_header.erb | 63 +-- website/source/layouts/_sidebar.erb | 26 ++ website/source/layouts/layout.erb | 1 + .../source/layouts/svg/_svg-by-hashicorp.erb | 18 + website/source/layouts/svg/_svg-download.erb | 4 + website/source/layouts/svg/_svg-github.erb | 9 + .../layouts/svg/_svg-hashicorp-logo.erb | 7 + 20 files changed, 791 insertions(+), 413 deletions(-) create mode 100644 website/source/assets/javascripts/app/Sidebar.js create mode 100644 website/source/assets/stylesheets/_sidebar.scss create mode 100755 website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss create mode 100644 website/source/assets/stylesheets/hashicorp-shared/_hashicorp-sidebar.scss create mode 100755 website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss create mode 100755 website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss create mode 100644 website/source/layouts/_sidebar.erb create mode 100644 website/source/layouts/svg/_svg-by-hashicorp.erb create mode 100644 website/source/layouts/svg/_svg-download.erb create mode 100644 website/source/layouts/svg/_svg-github.erb create mode 100644 website/source/layouts/svg/_svg-hashicorp-logo.erb diff --git a/website/Gemfile.lock b/website/Gemfile.lock index 7034f311e..725b16df3 100644 --- a/website/Gemfile.lock +++ b/website/Gemfile.lock @@ -186,6 +186,3 @@ PLATFORMS DEPENDENCIES middleman-hashicorp! - -BUNDLED WITH - 1.10.6 diff --git a/website/source/assets/javascripts/app/Init.js b/website/source/assets/javascripts/app/Init.js index 074c95d8d..06e772beb 100644 --- a/website/source/assets/javascripts/app/Init.js +++ b/website/source/assets/javascripts/app/Init.js @@ -21,6 +21,12 @@ var Init = { if (this.Pages[id]) { this.Pages[id](); } + //always init sidebar + Init.initializeSidebar(); + }, + + initializeSidebar: function(){ + new Sidebar(); }, generateAnimatedLogo: function(){ diff --git a/website/source/assets/javascripts/app/Sidebar.js b/website/source/assets/javascripts/app/Sidebar.js new file mode 100644 index 000000000..bb5d4cc9e --- /dev/null +++ b/website/source/assets/javascripts/app/Sidebar.js @@ -0,0 +1,50 @@ +(function(){ + +Sidebar = Base.extend({ + + $body: null, + $overlay: null, + $sidebar: null, + $sidebarHeader: null, + $sidebarImg: null, + $toggleButton: null, + + constructor: function(){ + this.$body = $('body'); + this.$overlay = $('.sidebar-overlay'); + this.$sidebar = $('#sidebar'); + this.$sidebarHeader = $('#sidebar .sidebar-header'); + this.$toggleButton = $('.navbar-toggle'); + this.sidebarImg = this.$sidebarHeader.css('background-image'); + + this.addEventListeners(); + }, + + addEventListeners: function(){ + var _this = this; + + _this.$toggleButton.on('click', function() { + _this.$sidebar.toggleClass('open'); + if ((_this.$sidebar.hasClass('sidebar-fixed-left') || _this.$sidebar.hasClass('sidebar-fixed-right')) && _this.$sidebar.hasClass('open')) { + _this.$overlay.addClass('active'); + _this.$body.css('overflow', 'hidden'); + } else { + _this.$overlay.removeClass('active'); + _this.$body.css('overflow', 'auto'); + } + + return false; + }); + + _this.$overlay.on('click', function() { + $(this).removeClass('active'); + _this.$body.css('overflow', 'auto'); + _this.$sidebar.removeClass('open'); + }); + } + +}); + +window.Sidebar = Sidebar; + +})(); diff --git a/website/source/assets/javascripts/application.js b/website/source/assets/javascripts/application.js index 9180016ef..15542d8dc 100644 --- a/website/source/assets/javascripts/application.js +++ b/website/source/assets/javascripts/application.js @@ -21,4 +21,5 @@ //= require app/Engine.Shape //= require app/Engine.Shape.Puller //= require app/Engine.Typewriter +//= require app/Sidebar //= require app/Init diff --git a/website/source/assets/stylesheets/_fonts.scss b/website/source/assets/stylesheets/_fonts.scss index 3f1d4aaed..c14cb7071 100755 --- a/website/source/assets/stylesheets/_fonts.scss +++ b/website/source/assets/stylesheets/_fonts.scss @@ -2,6 +2,7 @@ // Typography // -------------------------------------------------- + //light .rls-l{ font-family: $font-family-lato; diff --git a/website/source/assets/stylesheets/_header.scss b/website/source/assets/stylesheets/_header.scss index 408d11d78..192334442 100755 --- a/website/source/assets/stylesheets/_header.scss +++ b/website/source/assets/stylesheets/_header.scss @@ -1,382 +1,58 @@ // // Header +// - Project Specific +// - edits should be made here // -------------------------------------------------- -body.page-sub{ - - .terra-btn{ - background-color: rgba(130, 47, 247, 1); - } - - #header{ - height: 90px; - background-color: $purple; - - .navbar-collapse{ - background-color: rgba(255, 255, 255, 0.98); - } - - .nav-logo{ - height: 90px; - } - - .nav-white{ - height: 90px; - background-color: white; - } - - .main-links.navbar-nav{ - float: left !important; - li > a { - color: black; - @include transition( color 0.3s ease ); - } - } - - .buttons.nav > li > a, .buttons.nav > li > a { - //background-color: lighten($purple, 1%); - @include transition( background-color 0.3s ease ); - } - - .buttons.nav > li > a:hover, .buttons.nav > li > a:focus { - background-color: black; - @include transition( background-color 0.3s ease ); - } - - .main-links.nav > li > a:hover, .main-links.nav > li > a:focus { - color: $purple; - @include transition( color 0.3s ease ); - } - } -} - #header { - position: relative; - color: $white; - text-rendering: optimizeLegibility; - margin-bottom: 0; - - &.navbar-static-top{ - height:70px; - - -webkit-transform:translate3d(0,0,0); - -moz-transform:translate3d(0,0,0); - -ms-transform:translate3d(0,0,0); - -o-transform:translate3d(0,0,0); - transform:translate3d(0,0,0); - z-index: 1000; - } - - a{ - color: $white; - } - - .navbar-toggle{ - margin-top: 26px; - margin-bottom: 14px; - margin-right: 0; - border: 2px solid $white; - border-radius: 0; - .icon-bar{ - border: 1px solid $white; - border-radius: 0; - } - } - .navbar-brand { - &.logo{ - margin-top: 15px; - padding: 5px 0 0 68px; - height: 56px; - line-height: 56px; - font-size: 24px; - @include lato-light(); - text-transform: uppercase; - background: image-url('consul-header-logo.png') 0 0 no-repeat; - @include img-retina("header-logo.png", "header-logo@2x.png", 50px, 56px); - -webkit-font-smoothing: default; + .logo{ + color: $black; + font-size: 28px; + background: image-url('../images/logo-header.png') 0 0 no-repeat; + @include img-retina("../images/logo-header.png", "../images/logo-header@2x.png", $project-logo-size, $project-logo-size); + background-position: 0 center; + + &:hover{ + color: $orange; + } } - } - .navbar-nav{ - -webkit-font-smoothing: antialiased; - li{ - position: relative; - - > a { - font-size: 12px; - text-transform: uppercase; - letter-spacing: 3px; - padding-left: 22px; - @include transition( color 0.3s ease ); - } - - &.first{ - >a{ - padding-left: 15px; + .by{ + color: $black; + &:hover{ + svg{ + line{ + stroke: $purple; + } } } } } - .nav > li > a:hover, .nav > li > a:focus { - background-color: transparent; - color: lighten($purple, 15%); - @include transition( color 0.3s ease ); + .buttons{ + margin-top: 2px; //baseline everything + + ul.navbar-nav{ + li { + &:hover{ + svg path{ + fill: $purple; + } + } + + svg path{ + fill: $white; + } + } + } } - .main-links.navbar-nav{ - margin-top: 28px; - - li + li{ - padding-left: 6px; - } - - li + li::before { - content: ""; - position: absolute; - left: 0; - top: 7px; - width: 1px; - height: 12px; - background-color: $purple; - @include skewY(24deg); - padding-right: 0; - } - + .main-links, + .external-links { li > a { - //border-bottom: 2px solid rgba(255, 255, 255, .2); - line-height: 26px; - margin: 0 8px; - padding: 0 0 0 4px; - } - - } - - .buttons.navbar-nav{ - margin-top: 25px; - margin-left: 30px; - - li{ - &.first{ - margin-right: 13px; - } - - &.download{ - a{ - padding-left: 30px; - background: image-url("header-download-icon.png") 12px 8px no-repeat; - @include img-retina("header-download-icon.png", "header-download-icon@2x.png", 12px, 13px); - } - } - - &.github{ - a{ - background: image-url("header-github-icon.png") 12px 7px no-repeat; - @include img-retina("header-github-icon.png", "header-github-icon@2x.png", 12px, 13px); - } - } - } - - li > a { - color: white; - padding-top: 4px; - padding-bottom: 4px; - padding-left: 32px; - padding-right: 12px; - letter-spacing: 0.05em; + @include project-a-style(); + font-weight: 400; } } } - -@media (min-width: 1200px) { - - #header{ - .main-links.navbar-nav{ - margin-top: 28px; - - li + li{ - padding-left: 6px; - } - - li + li::before { - content: ""; - position: absolute; - left: 0; - top: 9px; - width: 6px; - height: 8px; - background-color: $purple; - @include skewY(24deg); - padding-right: 8px; - } - - li > a { - //border-bottom: 2px solid rgba(255, 255, 255, .2); - line-height: 26px; - margin: 0 12px; - padding: 0 0 0 4px; - } - - } - } -} - -@media (min-width: 992px) { - - .collapse{ - margin-top: 8px; - } - - //homepage has more space at this width to accommodate chevrons - .page-home{ - #header{ - .main-links.navbar-nav{ - li + li{ - padding-left: 6px; - } - - li + li::before { - content: ""; - position: absolute; - left: 0; - top: 9px; - width: 6px; - height: 8px; - background-color: $purple; - @include skewY(24deg); - padding-right: 8px; - } - } - } - } -} - - - -@media (min-width: 768px) and (max-width: 992px) { - - body.page-home{ - .nav-logo{ - width: 30%; - } - .nav-white{ - margin-top: 8px; - width: 70%; - } - .buttons.navbar-nav{ - li{ - > a{ - padding-right: 4px !important; - text-indent: -9999px; - white-space: nowrap; - } - } - } - } -} - - -@media (max-width: 992px) { - - #header { - .navbar-brand { - &.logo{ - span{ - width: 120px; - height: 39px; - margin-top: 12px; - background-size: 120px 39px; - } - } - } - } -} - -@media (max-width: 768px) { - - body.page-sub{ - #header{ - .nav-white{ - background-color: transparent; - } - } - } - - #header{ - .buttons.navbar-nav{ - float: none !important; - margin: 0; - padding-bottom: 0 !important; - - li{ - &.first{ - margin-right: 0; - } - } - } - } - - //#footer, - #header{ - .buttons.navbar-nav, - .main-links.navbar-nav{ - display: block; - padding-bottom: 15px; - li{ - display: block; - float: none; - margin-top: 15px; - } - - .li-under a::after, - li + li::before { - display: none; - } - } - } - - //#footer, - #header{ - .main-links.navbar-nav{ - float: left !important; - li > a { - padding: 0; - padding-left: 0; - line-height: 22px; - } - } - } -} - -@media (max-width: 763px) { - .navbar-static-top { - .nav-white { - background-color:rgba(0,0,0,0.5); - } - } -} - -@media (max-width: 320px) { - - #header{ - .navbar-brand { - &.logo{ - padding:0 0 0 54px !important; - font-size: 20px !important; - line-height:42px !important; - margin-top: 23px !important ; - @include img-retina("../images/header-logo.png", "../images/header-logo@2x.png", 39px, 44px); - } - } - - } - - #feature-auto{ - .terminal-text{ - line-height: 48px !important; - font-size: 20px !important; - } - } - -} diff --git a/website/source/assets/stylesheets/_sidebar.scss b/website/source/assets/stylesheets/_sidebar.scss new file mode 100644 index 000000000..4c632d480 --- /dev/null +++ b/website/source/assets/stylesheets/_sidebar.scss @@ -0,0 +1,23 @@ +// +// Sidebar +// - Project Specific +// - Make sidebar edits here +// -------------------------------------------------- + +.sidebar { + .sidebar-nav { + // Links + //---------------- + li { + a { + color: $black; + + svg{ + path{ + fill: $black; + } + } + } + } + } +} diff --git a/website/source/assets/stylesheets/_utilities.scss b/website/source/assets/stylesheets/_utilities.scss index b01423f50..4f30e502b 100755 --- a/website/source/assets/stylesheets/_utilities.scss +++ b/website/source/assets/stylesheets/_utilities.scss @@ -2,27 +2,11 @@ // Utility classes // -------------------------------------------------- - -// -// ------------------------- - @mixin anti-alias() { text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; } -@mixin consul-gradient-bg() { - background: #694a9c; /* Old browsers */ - background: -moz-linear-gradient(left, #694a9c 0%, #cd2028 100%); /* FF3.6+ */ - background: -webkit-gradient(linear, left top, right top, color-stop(0%,#694a9c), color-stop(100%,#cd2028)); /* Chrome,Safari4+ */ - background: -webkit-linear-gradient(left, #694a9c 0%,#cd2028 100%); /* Chrome10+,Safari5.1+ */ - background: -o-linear-gradient(left, #694a9c 0%,#cd2028 100%); /* Opera 11.10+ */ - background: -ms-linear-gradient(left, #694a9c 0%,#cd2028 100%); /* IE10+ */ - background: linear-gradient(to right, #694a9c 0%,#cd2028 100%); /* W3C */ - filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#694a9c', endColorstr='#cd2028',GradientType=1 ); /* IE6-9 */ - -} - @mixin lato-light() { font-family: $font-family-lato; font-weight: 300; diff --git a/website/source/assets/stylesheets/application.scss b/website/source/assets/stylesheets/application.scss index 95ae64b73..3776f9056 100755 --- a/website/source/assets/stylesheets/application.scss +++ b/website/source/assets/stylesheets/application.scss @@ -1,13 +1,12 @@ @import 'bootstrap-sprockets'; @import 'bootstrap'; -@import url("//fonts.googleapis.com/css?family=Lato:300,400,700"); +@import url("//fonts.googleapis.com/css?family=Lato:300,400,700|Open+Sans:300,400,600"); // Core variables and mixins @import '_variables'; -@import '_mixins'; -// Utility classes +// Utility @import '_utilities'; // Core CSS @@ -16,11 +15,18 @@ //Global Site @import '_global'; +// Hashicorp Shared Project Styles +@import 'hashicorp-shared/_project-utility'; +@import 'hashicorp-shared/_hashicorp-utility'; +@import 'hashicorp-shared/_hashicorp-header'; +@import 'hashicorp-shared/_hashicorp-sidebar'; + // Components @import '_header'; @import '_footer'; @import '_jumbotron'; @import '_buttons'; +@import '_sidebar'; // Pages @import '_home'; diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss new file mode 100755 index 000000000..915820c33 --- /dev/null +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss @@ -0,0 +1,166 @@ +// +// Hashicorp header +// - Shared throughout projects +// - Edits should not be made here +// -------------------------------------------------- + +#header { + position: relative; + color: $white; + text-rendering: optimizeLegibility; + margin-bottom: 0; + transition: all 1s ease; + + &.white{ + .navbar-brand { + .by{ + svg{ + path, + polygon{ + fill: white; + } + line{ + stroke: white; + } + } + } + } + } + + .navbar-header{ + .navbar-toggle{ + height: $header-height; + margin: 0; + padding-right: 15px; + border-radius: 0; + .icon-bar{ + border: 1px solid $black; + border-radius: 0; + } + } + } + + .navbar-brand { + display: block; + height: $header-height; + padding: 0; + margin: 0 10px 0 0 ; + + .logo{ + display: inline-block; + height: $header-height; + vertical-align:top; + padding: 0; + line-height: $header-height; + padding-left: $project-logo-size + $project-logo-pad-left; + background-position: 0 center; + + &:hover{ + @include transition(all 300ms ease-in); + text-decoration: none; + } + } + + .by{ + display: inline-block; + vertical-align:top; + height: $header-height; + margin-left: 3px; + padding-top: 2px; + line-height: $header-height; + font-family: $header-font-family; + font-weight: 300; + font-size: 0; + text-decoration: none; + + .svg-wrap{ + font-size: 13px; + } + + svg{ + &.svg-by{ + width: $by-hashicorp-width; + height: $by-hashicorp-height; + margin-bottom: -4px; + margin-left: 4px; + } + + &.svg-logo{ + width: 16px; + height: 16px; + margin-bottom: -3px; + margin-left: 4px; + } + + path, + polygon{ + fill: black; + @include transition(all 300ms ease-in); + + &:hover{ + @include transition(all 300ms ease-in); + } + } + line{ + stroke: black; + + &:hover{ + @include transition(all 300ms ease-in); + } + } + } + } + } + + .external-links { + li { + position: relative; + + svg path{ + @include transition( all 0.3s ease ); + } + + &:hover{ + svg path{ + @include transition( all 0.3s ease ); + } + } + + &.download{ + margin-right: 10px; + } + + >a { + padding-left: 12px !important; + svg{ + position: absolute; + left: -12px; + top: 50%; + margin-top: -7px; + width: 14px; + height: 14px; + } + } + } + } + + .main-links{ + margin-right: $nav-margin-right * 2; + } + + .main-links, + .external-links { + li > a { + @include hashi-a-style(); + margin: 0 10px; + padding-top: 1px; + line-height: $header-height; + } + } + + .nav > li > a:hover, .nav > li > a:focus { + background-color: transparent; + color: $black; + @include transition( color 0.3s ease ); + } +} diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-sidebar.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-sidebar.scss new file mode 100644 index 000000000..4a5a6ae07 --- /dev/null +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-sidebar.scss @@ -0,0 +1,293 @@ +// +// Hashicorp Sidebar +// - Shared throughout projects +// - Edits should not be made here +// -------------------------------------------------- + +// Base variables +// -------------------------------------------------- +$screen-tablet: 768px; + +$gray-darker: #212121; // #212121 - text +$gray-secondary: #757575; // #757575 - secondary text, icons +$gray: #bdbdbd; // #bdbdbd - hint text +$gray-light: #e0e0e0; // #e0e0e0 - divider +$gray-lighter: #f5f5f5; // #f5f5f5 - background +$link-color: $gray-darker; +$link-bg: transparent; +$link-hover-color: $gray-lighter; +$link-hover-bg: $gray-lighter; +$link-active-color: $gray-darker; +$link-active-bg: $gray-light; +$link-disabled-color: $gray-light; +$link-disabled-bg: transparent; + +/* -- Sidebar style ------------------------------- */ + +// Sidebar variables +// -------------------------------------------------- +$zindex-sidebar-fixed: 1035; + +$sidebar-desktop-width: 280px; +$sidebar-width: 240px; + +$sidebar-padding: 16px; +$sidebar-divider: $sidebar-padding/2; + +$sidebar-icon-width: 40px; +$sidebar-icon-height: 20px; + +@mixin sidebar-nav-base { + text-align: center; + + &:last-child{ + border-bottom: none; + } + + li > a { + background-color: $link-bg; + } + li:hover > a { + background-color: $link-hover-bg; + } + li:focus > a, li > a:focus { + background-color: $link-bg; + } + + > .open > a { + &, + &:hover, + &:focus { + background-color: $link-hover-bg; + } + } + + > .active > a { + &, + &:hover, + &:focus { + background-color: $link-active-bg; + } + } + > .disabled > a { + &, + &:hover, + &:focus { + background-color: $link-disabled-bg; + } + } + + // Dropdown menu items + > .dropdown { + // Remove background color from open dropdown + > .dropdown-menu { + background-color: $link-hover-bg; + + > li > a { + &:focus { + background-color: $link-hover-bg; + } + &:hover { + background-color: $link-hover-bg; + } + } + + > .active > a { + &, + &:hover, + &:focus { + color: $link-active-color; + background-color: $link-active-bg; + } + } + } + } +} + +// +// Sidebar +// -------------------------------------------------- + +// Sidebar Elements +// +// Basic style of sidebar elements +.sidebar { + position: relative; + display: block; + min-height: 100%; + overflow-y: auto; + overflow-x: hidden; + border: none; + @include transition(all 0.5s cubic-bezier(0.55, 0, 0.1, 1)); + @include clearfix(); + background-color: $white; + + ul{ + padding-left: 0; + list-style-type: none; + } + + .sidebar-divider, .divider { + width: 80%; + height: 1px; + margin: 8px auto; + background-color: lighten($gray, 20%); + } + + // Sidebar heading + //---------------- + .sidebar-header { + position: relative; + margin-bottom: $sidebar-padding; + @include transition(all .2s ease-in-out); + } + + .sidebar-image { + padding-top: 24px; + img { + display: block; + margin: 0 auto; + } + } + + + // Sidebar icons + //---------------- + .sidebar-icon { + display: inline-block; + height: $sidebar-icon-height; + margin-right: $sidebar-divider; + text-align: left; + font-size: $sidebar-icon-height; + vertical-align: middle; + + &:before, &:after { + vertical-align: middle; + } + } + + .sidebar-nav { + margin: 0; + padding: 0; + + @include sidebar-nav-base(); + + // Links + //---------------- + li { + position: relative; + list-style-type: none; + text-align: center; + + a { + position: relative; + cursor: pointer; + user-select: none; + @include hashi-a-style-core(); + + svg{ + top: 2px; + width: 14px; + height: 14px; + margin-bottom: -2px; + margin-right: 4px; + } + } + } + } +} + +// Sidebar toggling +// +// Hide sidebar +.sidebar { + width: 0; + @include translate3d(-$sidebar-desktop-width, 0, 0); + + &.open { + min-width: $sidebar-desktop-width; + width: $sidebar-desktop-width; + @include translate3d(0, 0, 0); + } +} + +// Sidebar positions: fix the left/right sidebars +.sidebar-fixed-left, +.sidebar-fixed-right, +.sidebar-stacked { + position: fixed; + top: 0; + bottom: 0; + z-index: $zindex-sidebar-fixed; +} +.sidebar-stacked { + left: 0; +} +.sidebar-fixed-left { + left: 0; + box-shadow: 2px 0px 25px rgba(0,0,0,0.15); + -webkit-box-shadow: 2px 0px 25px rgba(0,0,0,0.15); +} +.sidebar-fixed-right { + right: 0; + box-shadow: 0px 2px 25px rgba(0,0,0,0.15); + -webkit-box-shadow: 0px 2px 25px rgba(0,0,0,0.15); + + @include translate3d($sidebar-desktop-width, 0, 0); + &.open { + @include translate3d(0, 0, 0); + } + .icon-material-sidebar-arrow:before { + content: "\e614"; // icon-material-arrow-forward + } +} + +// Sidebar size +// +// Change size of sidebar and sidebar elements on small screens +@media (max-width: $screen-tablet) { + .sidebar.open { + min-width: $sidebar-width; + width: $sidebar-width; + } + + .sidebar .sidebar-header { + //height: $sidebar-width * 9/16; // 16:9 header dimension + } + + .sidebar .sidebar-image { + /* img { + width: $sidebar-width/4 - $sidebar-padding; + height: $sidebar-width/4 - $sidebar-padding; + } */ + } +} + +.sidebar-overlay { + visibility: hidden; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + opacity: 0; + background: $white; + z-index: $zindex-sidebar-fixed - 1; + + -webkit-transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); + -moz-transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); + transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0); +} + +.sidebar-overlay.active { + opacity: 0.3; + visibility: visible; + -webkit-transition-delay: 0; + -moz-transition-delay: 0; + transition-delay: 0; +} diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss new file mode 100755 index 000000000..be6c9f8fc --- /dev/null +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss @@ -0,0 +1,86 @@ +// +// Hashicorp Nav (header/footer) Utiliy Vars and Mixins +// +// Notes: +// - Include this in Application.scss before header and feature-footer +// - Open Sans Google (Semibold - 600) font needs to be included if not already +// -------------------------------------------------- + +// Variables +$font-family-open-sans: 'Open Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; +$header-font-family: $font-family-open-sans; +$header-font-weight: 600; // semi-bold + +$header-height: 74px; +$by-hashicorp-width: 74px; +$by-hashicorp-height: 16px; +$nav-margin-right: 12px; + +// Mixins +@mixin hashi-a-style-core{ + font-family: $header-font-family; + font-weight: $header-font-weight; + font-size: 14px; + //letter-spacing: 0.0625em; +} + +@mixin hashi-a-style{ + margin: 0 15px; + padding: 0; + line-height: 22px; + @include hashi-a-style-core(); + @include transition( color 0.3s ease ); + + &:hover{ + @include transition( color 0.3s ease ); + background-color: transparent; + } +} + +//general shared project mixins +@mixin img-retina($image1x, $image, $width, $height) { + background-image: url($image1x); + background-size: $width $height; + background-repeat: no-repeat; + + @media (min--moz-device-pixel-ratio: 1.3), + (-o-min-device-pixel-ratio: 2.6/2), + (-webkit-min-device-pixel-ratio: 1.3), + (min-device-pixel-ratio: 1.3), + (min-resolution: 1.3dppx) { + /* on retina, use image that's scaled by 2 */ + background-image: url($image); + background-size: $width $height; + } +} + +// +// ------------------------- +@mixin anti-alias() { + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; +} + +@mixin open-light() { + font-family: $font-family-open-sans; + font-weight: 300; +} + +@mixin open() { + font-family: $font-family-open-sans; + font-weight: 400; +} + +@mixin open-sb() { + font-family: $font-family-open-sans; + font-weight: 600; +} + +@mixin open-bold() { + font-family: $font-family-open-sans; + font-weight: 700; +} + +@mixin bez-1-transition{ + @include transition( all 300ms ease-in-out ); +} diff --git a/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss b/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss new file mode 100755 index 000000000..42910526a --- /dev/null +++ b/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss @@ -0,0 +1,17 @@ +// +// Mixins Specific to project +// - make edits to mixins here +// -------------------------------------------------- + +// Variables +$project-logo-size: 40px; +$project-logo-pad-left: 8px; + +// Mixins +@mixin project-a-style{ + color: $white; + + &:hover{ + color: $purple; + } +} diff --git a/website/source/layouts/_header.erb b/website/source/layouts/_header.erb index fa6119a29..484f551b8 100644 --- a/website/source/layouts/_header.erb +++ b/website/source/layouts/_header.erb @@ -1,30 +1,37 @@ - diff --git a/website/source/layouts/_sidebar.erb b/website/source/layouts/_sidebar.erb new file mode 100644 index 000000000..5a906142f --- /dev/null +++ b/website/source/layouts/_sidebar.erb @@ -0,0 +1,26 @@ + + + + + diff --git a/website/source/layouts/layout.erb b/website/source/layouts/layout.erb index 665a0a128..2b7a67363 100644 --- a/website/source/layouts/layout.erb +++ b/website/source/layouts/layout.erb @@ -1,4 +1,5 @@ <%= partial "layouts/meta" %> <%= partial "layouts/header" %> +<%= partial "layouts/sidebar" %> <%= yield %> <%= partial "layouts/footer" %> diff --git a/website/source/layouts/svg/_svg-by-hashicorp.erb b/website/source/layouts/svg/_svg-by-hashicorp.erb new file mode 100644 index 000000000..d89929590 --- /dev/null +++ b/website/source/layouts/svg/_svg-by-hashicorp.erb @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + diff --git a/website/source/layouts/svg/_svg-download.erb b/website/source/layouts/svg/_svg-download.erb new file mode 100644 index 000000000..6d8441fea --- /dev/null +++ b/website/source/layouts/svg/_svg-download.erb @@ -0,0 +1,4 @@ + + + diff --git a/website/source/layouts/svg/_svg-github.erb b/website/source/layouts/svg/_svg-github.erb new file mode 100644 index 000000000..f0264d5aa --- /dev/null +++ b/website/source/layouts/svg/_svg-github.erb @@ -0,0 +1,9 @@ + + + + diff --git a/website/source/layouts/svg/_svg-hashicorp-logo.erb b/website/source/layouts/svg/_svg-hashicorp-logo.erb new file mode 100644 index 000000000..60663e140 --- /dev/null +++ b/website/source/layouts/svg/_svg-hashicorp-logo.erb @@ -0,0 +1,7 @@ + From 1269d2a1568cfbe1bb1e2bfc274efd65c05802ae Mon Sep 17 00:00:00 2001 From: captainill Date: Fri, 6 Nov 2015 12:45:10 -0800 Subject: [PATCH 09/74] shared styles update --- .../stylesheets/hashicorp-shared/_hashicorp-header.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss index 915820c33..1578ad93a 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss @@ -14,6 +14,8 @@ &.white{ .navbar-brand { .by{ + color: white; + font-weight: 300; svg{ path, polygon{ @@ -67,9 +69,10 @@ height: $header-height; margin-left: 3px; padding-top: 2px; + color: black; line-height: $header-height; font-family: $header-font-family; - font-weight: 300; + font-weight: 600; font-size: 0; text-decoration: none; From a5f8ecfdd869b997f917993b5187f231ebf0e3d1 Mon Sep 17 00:00:00 2001 From: captainill Date: Fri, 6 Nov 2015 15:41:23 -0800 Subject: [PATCH 10/74] header styles complete + subpage --- .../assets/images/logo-header-black@2x.png | Bin 0 -> 1771 bytes .../{header-logo.png => logo-header.png} | Bin ...{header-logo@2x.png => logo-header@2x.png} | Bin .../source/assets/stylesheets/_header.scss | 45 +++++++++++++----- .../hashicorp-shared/_hashicorp-header.scss | 38 +++++++++++++-- .../hashicorp-shared/_hashicorp-utility.scss | 4 +- .../hashicorp-shared/_project-utility.scss | 7 ++- website/source/layouts/_sidebar.erb | 2 +- 8 files changed, 75 insertions(+), 21 deletions(-) create mode 100644 website/source/assets/images/logo-header-black@2x.png rename website/source/assets/images/{header-logo.png => logo-header.png} (100%) rename website/source/assets/images/{header-logo@2x.png => logo-header@2x.png} (100%) diff --git a/website/source/assets/images/logo-header-black@2x.png b/website/source/assets/images/logo-header-black@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..74521a66462127900dbb32d29c7024f8ebc041e9 GIT binary patch literal 1771 zcmb7_i8tHX7r?)5DYXRoiR9N-TY~9=h@}mo##S`e(g-C;Vl66`h+5j(8WLMjts*+6 zqzopt&7js$TFZ=#RtdEfRk38$(iZ)tf5PvcbMNQAd+$5%oO|whH{Hp>T2|_~6aWCS zwlrDY7q#eo@bY)fIDM3@i<4Z0GG5{2JQaEsX;y| z!|4J|kgY37{giF?*HvlD^Bl>W-Jg9Pp^$p|2AM_k%h?9mcqaSMCd(jT6Z0ImE$ z`5hzkmSeH2pEa@?2*o)vNOH4t{Nbh&a<5I(iOMBPOO4(6K6%IaE5-SfUz(7auz^!A z7shkYv?d)oY+$W7i+``-UMvmCt>4vf7*=-5dsGM;0L_%6F2?xSlcou3-{9JV%AP!2 zK5QWIu1loEJ4Gd}KKc7X!;n|XA8qxG-Lfz9CI2WV34rF}Vb_ zNxIy*6|&KVN}5!#7d}G?{_Yk>FGeZg1JxO6qOUr9g_bKok3T?HyM%Mt`L$5*axQG{ z{jOTp>ylX{%FFf2%OT7>*QQD0)n*(U*}c2taAYY-c||v<`v%6+{SX zgIO4-B4)S@bAdc$#QonbNfI0Hg_lOCgdQ*&)NP*RdH$ zt^%I{Mf^;Ywo;Frjt#1T4Q$WD7hUp9AX}r)d&~T)EDOrF&Lf% z_vQp;&pd`IK3w-@=QU~kYIBQ2&he4ybnC*>qO5xC-;0#C<8S8%_zsj*XGp_8RLarB z{K>zybsP*g6@<5U{P)f^_k{X0C;lx#ojBdo#m{QawUyoEBQ6z=pZ zM?KSwtJ|JJL2r#HQ`0{LHkztpQ{%ACqwV)uD{F9pWc!23^sx}dP=jw;b$s`+T_kR9 z{rl71Fs$Yct0NP+N^~Kc&Aynn`bVW7;bdPlN+l+u(llS*6GI-TpD#!Bm+)<$Va1TYA9NPdx!C96UMkkr z+?$Dh#=ABq77ZOfNgg5->KD5H3w9gh$LRFzul1}%{1l0;GDyNi?+n3fr_ydz+TpK9 zc62H3#2#MfF>NcxjJno(B{J~_G zTh(G@GQ^bShwvdj8`SP|(k$frh#o7X$F`Pp$Fr-Wq9UUGE{kTob*oan&36Bg7OU~$ z{(R;WU2i0Fs$6AB{(&pSOR+V)<17}E0P=-$ZOHg@6;BdyPnP5iR#7p?6JwKe} zK;sobXW=N<=GS`&w{*kRk}_8$ZCUbCI;W2rFAR)ouEa%^W_KceK=)WE#sGX9} z3@DsE{bz~0n7!ye>7W!g`PGW-8Q`cgNc1o-K+`OF2fElzH%`Y~%`PS^!2jtoL5)H` zU$@6;41!bbU{70 z|BY&I;3lyuD+)A=R-}S_b5F a { @include project-a-style(); - font-weight: 400; } } } diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss index 1578ad93a..f8b5974fb 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss @@ -6,13 +6,18 @@ #header { position: relative; - color: $white; + color: black; text-rendering: optimizeLegibility; margin-bottom: 0; transition: all 1s ease; &.white{ + color: white; .navbar-brand { + .logo { + color: white; + } + .by{ color: white; font-weight: 300; @@ -27,6 +32,27 @@ } } } + + .main-links, + .external-links { + li > a { + &:hover{ + opacity: 1; + } + } + } + + .nav > li > a:hover, .nav > li > a:focus { + color: white; + } + + .navbar-header{ + .navbar-toggle{ + .icon-bar{ + border: 1px solid white; + } + } + } } .navbar-header{ @@ -54,8 +80,9 @@ vertical-align:top; padding: 0; line-height: $header-height; - padding-left: $project-logo-size + $project-logo-pad-left; + padding-left: $project-logo-width + $project-logo-pad-left; background-position: 0 center; + @include transition(all 300ms ease-in); &:hover{ @include transition(all 300ms ease-in); @@ -106,6 +133,7 @@ } line{ stroke: black; + @include transition(all 300ms ease-in); &:hover{ @include transition(all 300ms ease-in); @@ -120,12 +148,12 @@ position: relative; svg path{ - @include transition( all 0.3s ease ); + @include transition( all 300ms ease-in ); } &:hover{ svg path{ - @include transition( all 0.3s ease ); + @include transition( all 300ms ease-in ); } } @@ -164,6 +192,6 @@ .nav > li > a:hover, .nav > li > a:focus { background-color: transparent; color: $black; - @include transition( color 0.3s ease ); + @include transition( all 300ms ease-in ); } } diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss index be6c9f8fc..38943f97c 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss @@ -29,10 +29,10 @@ $nav-margin-right: 12px; padding: 0; line-height: 22px; @include hashi-a-style-core(); - @include transition( color 0.3s ease ); + @include transition( all 300ms ease-in ); &:hover{ - @include transition( color 0.3s ease ); + @include transition( all 300ms ease-in ); background-color: transparent; } } diff --git a/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss b/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss index 42910526a..80368c269 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss @@ -4,14 +4,17 @@ // -------------------------------------------------- // Variables -$project-logo-size: 40px; +$project-logo-width: 38px; +$project-logo-height: 40px; $project-logo-pad-left: 8px; // Mixins @mixin project-a-style{ color: $white; + font-weight: 300; + opacity: .75; &:hover{ - color: $purple; + color: $white; } } diff --git a/website/source/layouts/_sidebar.erb b/website/source/layouts/_sidebar.erb index 5a906142f..9a13aab71 100644 --- a/website/source/layouts/_sidebar.erb +++ b/website/source/layouts/_sidebar.erb @@ -7,7 +7,7 @@ From 2d30d8f483fb22610045a2308ef5653b403677e0 Mon Sep 17 00:00:00 2001 From: captainill Date: Fri, 6 Nov 2015 15:45:02 -0800 Subject: [PATCH 11/74] fix incorrect link --- website/source/layouts/_sidebar.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/source/layouts/_sidebar.erb b/website/source/layouts/_sidebar.erb index 9a13aab71..757a0888e 100644 --- a/website/source/layouts/_sidebar.erb +++ b/website/source/layouts/_sidebar.erb @@ -21,6 +21,6 @@ From 8a1bf06815f3a961c761f1df93bff178d9a1222f Mon Sep 17 00:00:00 2001 From: captainill Date: Fri, 6 Nov 2015 16:01:39 -0800 Subject: [PATCH 12/74] responsive cleanup --- .../source/assets/stylesheets/_header.scss | 24 +++++++++++++++ .../hashicorp-shared/_hashicorp-header.scss | 30 +++++++++++++++++++ .../hashicorp-shared/_hashicorp-utility.scss | 1 + 3 files changed, 55 insertions(+) diff --git a/website/source/assets/stylesheets/_header.scss b/website/source/assets/stylesheets/_header.scss index fa3f0754a..551c20b85 100755 --- a/website/source/assets/stylesheets/_header.scss +++ b/website/source/assets/stylesheets/_header.scss @@ -79,3 +79,27 @@ body.page-sub{ } } } + +@media (max-width: 414px) { + #header { + .navbar-brand { + .logo{ + padding-left: 37px; + font-size: 18px; + @include img-retina("../images/logo-header.png", "../images/logo-header@2x.png", $project-logo-width * .75, $project-logo-height * .75); + //background-position: 0 45%; + } + } + } +} + + +@media (max-width: 320px) { + #header { + .navbar-brand { + .logo{ + font-size: 0 !important; //hide terraform text + } + } + } +} diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss index f8b5974fb..da89db584 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss @@ -195,3 +195,33 @@ @include transition( all 300ms ease-in ); } } + +@media (max-width: 414px) { + #header { + .navbar-header{ + .navbar-toggle{ + padding-top: 13px; + height: $header-mobile-height; + } + } + + .navbar-brand { + height: $header-mobile-height; + + .logo{ + height: $header-mobile-height; + line-height: $header-mobile-height; + } + .by{ + height: $header-mobile-height; + line-height: $header-mobile-height; + } + } + .main-links, + .external-links { + li > a { + line-height: $header-mobile-height; + } + } + } +} diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss index 38943f97c..c4105b112 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss @@ -12,6 +12,7 @@ $header-font-family: $font-family-open-sans; $header-font-weight: 600; // semi-bold $header-height: 74px; +$header-mobile-height: 60px; $by-hashicorp-width: 74px; $by-hashicorp-height: 16px; $nav-margin-right: 12px; From 7f53f82f0d1534e96d7a12e4a0cd1b2be20f313e Mon Sep 17 00:00:00 2001 From: captainill Date: Fri, 6 Nov 2015 16:06:48 -0800 Subject: [PATCH 13/74] responsive tweak --- .../assets/stylesheets/hashicorp-shared/_hashicorp-header.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss index da89db584..1cfb9f8ac 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss @@ -200,7 +200,7 @@ #header { .navbar-header{ .navbar-toggle{ - padding-top: 13px; + padding-top: 10px; height: $header-mobile-height; } } @@ -215,6 +215,7 @@ .by{ height: $header-mobile-height; line-height: $header-mobile-height; + padding-top: 0; } } .main-links, From b33c3fcd0dfcfc3c4a803ede96766cef4d65e1e4 Mon Sep 17 00:00:00 2001 From: captainill Date: Fri, 6 Nov 2015 21:01:14 -0800 Subject: [PATCH 14/74] whitespace --- .../source/assets/javascripts/app/Sidebar.js | 74 ++-- .../source/assets/stylesheets/_header.scss | 118 +++--- .../source/assets/stylesheets/_sidebar.scss | 24 +- .../hashicorp-shared/_hashicorp-header.scss | 358 ++++++++--------- .../hashicorp-shared/_hashicorp-sidebar.scss | 376 +++++++++--------- .../hashicorp-shared/_hashicorp-utility.scss | 56 +-- .../hashicorp-shared/_project-utility.scss | 12 +- 7 files changed, 509 insertions(+), 509 deletions(-) diff --git a/website/source/assets/javascripts/app/Sidebar.js b/website/source/assets/javascripts/app/Sidebar.js index bb5d4cc9e..b36e508c4 100644 --- a/website/source/assets/javascripts/app/Sidebar.js +++ b/website/source/assets/javascripts/app/Sidebar.js @@ -1,50 +1,50 @@ (function(){ -Sidebar = Base.extend({ + Sidebar = Base.extend({ - $body: null, - $overlay: null, - $sidebar: null, - $sidebarHeader: null, - $sidebarImg: null, - $toggleButton: null, + $body: null, + $overlay: null, + $sidebar: null, + $sidebarHeader: null, + $sidebarImg: null, + $toggleButton: null, - constructor: function(){ - this.$body = $('body'); - this.$overlay = $('.sidebar-overlay'); - this.$sidebar = $('#sidebar'); - this.$sidebarHeader = $('#sidebar .sidebar-header'); - this.$toggleButton = $('.navbar-toggle'); - this.sidebarImg = this.$sidebarHeader.css('background-image'); + constructor: function(){ + this.$body = $('body'); + this.$overlay = $('.sidebar-overlay'); + this.$sidebar = $('#sidebar'); + this.$sidebarHeader = $('#sidebar .sidebar-header'); + this.$toggleButton = $('.navbar-toggle'); + this.sidebarImg = this.$sidebarHeader.css('background-image'); - this.addEventListeners(); - }, + this.addEventListeners(); + }, - addEventListeners: function(){ - var _this = this; + addEventListeners: function(){ + var _this = this; - _this.$toggleButton.on('click', function() { - _this.$sidebar.toggleClass('open'); - if ((_this.$sidebar.hasClass('sidebar-fixed-left') || _this.$sidebar.hasClass('sidebar-fixed-right')) && _this.$sidebar.hasClass('open')) { - _this.$overlay.addClass('active'); - _this.$body.css('overflow', 'hidden'); - } else { - _this.$overlay.removeClass('active'); - _this.$body.css('overflow', 'auto'); - } + _this.$toggleButton.on('click', function() { + _this.$sidebar.toggleClass('open'); + if ((_this.$sidebar.hasClass('sidebar-fixed-left') || _this.$sidebar.hasClass('sidebar-fixed-right')) && _this.$sidebar.hasClass('open')) { + _this.$overlay.addClass('active'); + _this.$body.css('overflow', 'hidden'); + } else { + _this.$overlay.removeClass('active'); + _this.$body.css('overflow', 'auto'); + } - return false; - }); + return false; + }); - _this.$overlay.on('click', function() { - $(this).removeClass('active'); - _this.$body.css('overflow', 'auto'); - _this.$sidebar.removeClass('open'); - }); - } + _this.$overlay.on('click', function() { + $(this).removeClass('active'); + _this.$body.css('overflow', 'auto'); + _this.$sidebar.removeClass('open'); + }); + } -}); + }); -window.Sidebar = Sidebar; + window.Sidebar = Sidebar; })(); diff --git a/website/source/assets/stylesheets/_header.scss b/website/source/assets/stylesheets/_header.scss index 551c20b85..82a5cf69b 100755 --- a/website/source/assets/stylesheets/_header.scss +++ b/website/source/assets/stylesheets/_header.scss @@ -5,79 +5,79 @@ // -------------------------------------------------- body.page-sub{ - #header{ - background-color: $purple; + #header{ + background-color: $purple; - .navbar-brand { - .logo{ - &:hover{ - color: $black; - } - } - .by{ - &:hover{ - svg{ - line{ - stroke: $black; - } - } - } - } + .navbar-brand { + .logo{ + &:hover{ + color: $black; } } + .by{ + &:hover{ + svg{ + line{ + stroke: $black; + } + } + } + } + } + } } #header { - .navbar-brand { - .logo{ - font-size: 20px; - text-transform: uppercase; - @include lato-light(); - background: image-url('../images/logo-header.png') 0 0 no-repeat; - @include img-retina("../images/logo-header.png", "../images/logo-header@2x.png", $project-logo-width, $project-logo-height); - background-position: 0 45%; + .navbar-brand { + .logo{ + font-size: 20px; + text-transform: uppercase; + @include lato-light(); + background: image-url('../images/logo-header.png') 0 0 no-repeat; + @include img-retina("../images/logo-header.png", "../images/logo-header@2x.png", $project-logo-width, $project-logo-height); + background-position: 0 45%; - &:hover{ - color: $purple; - } - } - - .by{ - color: $black; - &:hover{ - svg{ - line{ - stroke: $purple; - } - } - } - } + &:hover{ + color: $purple; + } } - .buttons{ - margin-top: 2px; //baseline everything - - ul.navbar-nav{ - li { - // &:hover{ - // svg path{ - // fill: $purple; - // } - // } - - svg path{ - fill: $white; - } - } + .by{ + color: $black; + &:hover{ + svg{ + line{ + stroke: $purple; + } } + } } + } - .main-links, - .external-links { - li > a { - @include project-a-style(); + .buttons{ + margin-top: 2px; //baseline everything + + ul.navbar-nav{ + li { + // &:hover{ + // svg path{ + // fill: $purple; + // } + // } + + svg path{ + fill: $white; } + } } + } + + .main-links, + .external-links { + li > a { + @include project-a-style(); + } + } } @media (max-width: 414px) { diff --git a/website/source/assets/stylesheets/_sidebar.scss b/website/source/assets/stylesheets/_sidebar.scss index 4c632d480..45a4ee64f 100644 --- a/website/source/assets/stylesheets/_sidebar.scss +++ b/website/source/assets/stylesheets/_sidebar.scss @@ -5,19 +5,19 @@ // -------------------------------------------------- .sidebar { - .sidebar-nav { - // Links - //---------------- - li { - a { - color: $black; + .sidebar-nav { + // Links + //---------------- + li { + a { + color: $black; - svg{ - path{ - fill: $black; - } - } - } + svg{ + path{ + fill: $black; + } } + } } + } } diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss index 1cfb9f8ac..c9bc593b6 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss @@ -5,195 +5,195 @@ // -------------------------------------------------- #header { - position: relative; - color: black; - text-rendering: optimizeLegibility; - margin-bottom: 0; - transition: all 1s ease; - - &.white{ - color: white; - .navbar-brand { - .logo { - color: white; - } - - .by{ - color: white; - font-weight: 300; - svg{ - path, - polygon{ - fill: white; - } - line{ - stroke: white; - } - } - } - } - - .main-links, - .external-links { - li > a { - &:hover{ - opacity: 1; - } - } - } - - .nav > li > a:hover, .nav > li > a:focus { - color: white; - } - - .navbar-header{ - .navbar-toggle{ - .icon-bar{ - border: 1px solid white; - } - } - } - } - - .navbar-header{ - .navbar-toggle{ - height: $header-height; - margin: 0; - padding-right: 15px; - border-radius: 0; - .icon-bar{ - border: 1px solid $black; - border-radius: 0; - } - } - } + position: relative; + color: black; + text-rendering: optimizeLegibility; + margin-bottom: 0; + transition: all 1s ease; + &.white{ + color: white; .navbar-brand { - display: block; - height: $header-height; - padding: 0; - margin: 0 10px 0 0 ; + .logo { + color: white; + } - .logo{ - display: inline-block; - height: $header-height; - vertical-align:top; - padding: 0; - line-height: $header-height; - padding-left: $project-logo-width + $project-logo-pad-left; - background-position: 0 center; - @include transition(all 300ms ease-in); - - &:hover{ - @include transition(all 300ms ease-in); - text-decoration: none; - } + .by{ + color: white; + font-weight: 300; + svg{ + path, + polygon{ + fill: white; + } + line{ + stroke: white; + } } - - .by{ - display: inline-block; - vertical-align:top; - height: $header-height; - margin-left: 3px; - padding-top: 2px; - color: black; - line-height: $header-height; - font-family: $header-font-family; - font-weight: 600; - font-size: 0; - text-decoration: none; - - .svg-wrap{ - font-size: 13px; - } - - svg{ - &.svg-by{ - width: $by-hashicorp-width; - height: $by-hashicorp-height; - margin-bottom: -4px; - margin-left: 4px; - } - - &.svg-logo{ - width: 16px; - height: 16px; - margin-bottom: -3px; - margin-left: 4px; - } - - path, - polygon{ - fill: black; - @include transition(all 300ms ease-in); - - &:hover{ - @include transition(all 300ms ease-in); - } - } - line{ - stroke: black; - @include transition(all 300ms ease-in); - - &:hover{ - @include transition(all 300ms ease-in); - } - } - } - } - } - - .external-links { - li { - position: relative; - - svg path{ - @include transition( all 300ms ease-in ); - } - - &:hover{ - svg path{ - @include transition( all 300ms ease-in ); - } - } - - &.download{ - margin-right: 10px; - } - - >a { - padding-left: 12px !important; - svg{ - position: absolute; - left: -12px; - top: 50%; - margin-top: -7px; - width: 14px; - height: 14px; - } - } - } - } - - .main-links{ - margin-right: $nav-margin-right * 2; + } } .main-links, .external-links { - li > a { - @include hashi-a-style(); - margin: 0 10px; - padding-top: 1px; - line-height: $header-height; + li > a { + &:hover{ + opacity: 1; } + } } .nav > li > a:hover, .nav > li > a:focus { - background-color: transparent; - color: $black; - @include transition( all 300ms ease-in ); + color: white; } + + .navbar-header{ + .navbar-toggle{ + .icon-bar{ + border: 1px solid white; + } + } + } + } + + .navbar-header{ + .navbar-toggle{ + height: $header-height; + margin: 0; + padding-right: 15px; + border-radius: 0; + .icon-bar{ + border: 1px solid $black; + border-radius: 0; + } + } + } + + .navbar-brand { + display: block; + height: $header-height; + padding: 0; + margin: 0 10px 0 0 ; + + .logo{ + display: inline-block; + height: $header-height; + vertical-align:top; + padding: 0; + line-height: $header-height; + padding-left: $project-logo-width + $project-logo-pad-left; + background-position: 0 center; + @include transition(all 300ms ease-in); + + &:hover{ + @include transition(all 300ms ease-in); + text-decoration: none; + } + } + + .by{ + display: inline-block; + vertical-align:top; + height: $header-height; + margin-left: 3px; + padding-top: 2px; + color: black; + line-height: $header-height; + font-family: $header-font-family; + font-weight: 600; + font-size: 0; + text-decoration: none; + + .svg-wrap{ + font-size: 13px; + } + + svg{ + &.svg-by{ + width: $by-hashicorp-width; + height: $by-hashicorp-height; + margin-bottom: -4px; + margin-left: 4px; + } + + &.svg-logo{ + width: 16px; + height: 16px; + margin-bottom: -3px; + margin-left: 4px; + } + + path, + polygon{ + fill: black; + @include transition(all 300ms ease-in); + + &:hover{ + @include transition(all 300ms ease-in); + } + } + line{ + stroke: black; + @include transition(all 300ms ease-in); + + &:hover{ + @include transition(all 300ms ease-in); + } + } + } + } + } + + .external-links { + li { + position: relative; + + svg path{ + @include transition( all 300ms ease-in ); + } + + &:hover{ + svg path{ + @include transition( all 300ms ease-in ); + } + } + + &.download{ + margin-right: 10px; + } + + > a { + padding-left: 12px !important; + svg{ + position: absolute; + left: -12px; + top: 50%; + margin-top: -7px; + width: 14px; + height: 14px; + } + } + } + } + + .main-links{ + margin-right: $nav-margin-right * 2; + } + + .main-links, + .external-links { + li > a { + @include hashi-a-style(); + margin: 0 10px; + padding-top: 1px; + line-height: $header-height; + } + } + + .nav > li > a:hover, .nav > li > a:focus { + background-color: transparent; + color: $black; + @include transition( all 300ms ease-in ); + } } @media (max-width: 414px) { @@ -220,9 +220,9 @@ } .main-links, .external-links { - li > a { - line-height: $header-mobile-height; - } + li > a { + line-height: $header-mobile-height; + } } } } diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-sidebar.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-sidebar.scss index 4a5a6ae07..99f77f6c5 100644 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-sidebar.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-sidebar.scss @@ -38,70 +38,70 @@ $sidebar-icon-width: 40px; $sidebar-icon-height: 20px; @mixin sidebar-nav-base { - text-align: center; + text-align: center; - &:last-child{ - border-bottom: none; - } + &:last-child{ + border-bottom: none; + } - li > a { - background-color: $link-bg; - } - li:hover > a { - background-color: $link-hover-bg; - } - li:focus > a, li > a:focus { - background-color: $link-bg; - } + li > a { + background-color: $link-bg; + } + li:hover > a { + background-color: $link-hover-bg; + } + li:focus > a, li > a:focus { + background-color: $link-bg; + } - > .open > a { + > .open > a { + &, + &:hover, + &:focus { + background-color: $link-hover-bg; + } + } + + > .active > a { + &, + &:hover, + &:focus { + background-color: $link-active-bg; + } + } + > .disabled > a { + &, + &:hover, + &:focus { + background-color: $link-disabled-bg; + } + } + + // Dropdown menu items + > .dropdown { + // Remove background color from open dropdown + > .dropdown-menu { + background-color: $link-hover-bg; + + > li > a { + &:focus { + background-color: $link-hover-bg; + } + &:hover { + background-color: $link-hover-bg; + } + } + + > .active > a { &, &:hover, &:focus { - background-color: $link-hover-bg; - } - } - - > .active > a { - &, - &:hover, - &:focus { - background-color: $link-active-bg; - } - } - > .disabled > a { - &, - &:hover, - &:focus { - background-color: $link-disabled-bg; - } - } - - // Dropdown menu items - > .dropdown { - // Remove background color from open dropdown - > .dropdown-menu { - background-color: $link-hover-bg; - - > li > a { - &:focus { - background-color: $link-hover-bg; - } - &:hover { - background-color: $link-hover-bg; - } - } - - > .active > a { - &, - &:hover, - &:focus { - color: $link-active-color; - background-color: $link-active-bg; - } - } + color: $link-active-color; + background-color: $link-active-bg; } + } } + } } // @@ -112,182 +112,182 @@ $sidebar-icon-height: 20px; // // Basic style of sidebar elements .sidebar { + position: relative; + display: block; + min-height: 100%; + overflow-y: auto; + overflow-x: hidden; + border: none; + @include transition(all 0.5s cubic-bezier(0.55, 0, 0.1, 1)); + @include clearfix(); + background-color: $white; + + ul{ + padding-left: 0; + list-style-type: none; + } + + .sidebar-divider, .divider { + width: 80%; + height: 1px; + margin: 8px auto; + background-color: lighten($gray, 20%); + } + + // Sidebar heading + //---------------- + .sidebar-header { position: relative; - display: block; - min-height: 100%; - overflow-y: auto; - overflow-x: hidden; - border: none; - @include transition(all 0.5s cubic-bezier(0.55, 0, 0.1, 1)); - @include clearfix(); - background-color: $white; + margin-bottom: $sidebar-padding; + @include transition(all .2s ease-in-out); + } - ul{ - padding-left: 0; - list-style-type: none; + .sidebar-image { + padding-top: 24px; + img { + display: block; + margin: 0 auto; } + } - .sidebar-divider, .divider { - width: 80%; - height: 1px; - margin: 8px auto; - background-color: lighten($gray, 20%); + + // Sidebar icons + //---------------- + .sidebar-icon { + display: inline-block; + height: $sidebar-icon-height; + margin-right: $sidebar-divider; + text-align: left; + font-size: $sidebar-icon-height; + vertical-align: middle; + + &:before, &:after { + vertical-align: middle; } + } - // Sidebar heading + .sidebar-nav { + margin: 0; + padding: 0; + + @include sidebar-nav-base(); + + // Links //---------------- - .sidebar-header { + li { + position: relative; + list-style-type: none; + text-align: center; + + a { position: relative; - margin-bottom: $sidebar-padding; - @include transition(all .2s ease-in-out); - } + cursor: pointer; + user-select: none; + @include hashi-a-style-core(); - .sidebar-image { - padding-top: 24px; - img { - display: block; - margin: 0 auto; - } - } - - - // Sidebar icons - //---------------- - .sidebar-icon { - display: inline-block; - height: $sidebar-icon-height; - margin-right: $sidebar-divider; - text-align: left; - font-size: $sidebar-icon-height; - vertical-align: middle; - - &:before, &:after { - vertical-align: middle; - } - } - - .sidebar-nav { - margin: 0; - padding: 0; - - @include sidebar-nav-base(); - - // Links - //---------------- - li { - position: relative; - list-style-type: none; - text-align: center; - - a { - position: relative; - cursor: pointer; - user-select: none; - @include hashi-a-style-core(); - - svg{ - top: 2px; - width: 14px; - height: 14px; - margin-bottom: -2px; - margin-right: 4px; - } - } + svg{ + top: 2px; + width: 14px; + height: 14px; + margin-bottom: -2px; + margin-right: 4px; } + } } + } } // Sidebar toggling // // Hide sidebar .sidebar { - width: 0; - @include translate3d(-$sidebar-desktop-width, 0, 0); + width: 0; + @include translate3d(-$sidebar-desktop-width, 0, 0); - &.open { - min-width: $sidebar-desktop-width; - width: $sidebar-desktop-width; - @include translate3d(0, 0, 0); - } + &.open { + min-width: $sidebar-desktop-width; + width: $sidebar-desktop-width; + @include translate3d(0, 0, 0); + } } // Sidebar positions: fix the left/right sidebars .sidebar-fixed-left, .sidebar-fixed-right, .sidebar-stacked { - position: fixed; - top: 0; - bottom: 0; - z-index: $zindex-sidebar-fixed; + position: fixed; + top: 0; + bottom: 0; + z-index: $zindex-sidebar-fixed; } .sidebar-stacked { - left: 0; + left: 0; } .sidebar-fixed-left { - left: 0; - box-shadow: 2px 0px 25px rgba(0,0,0,0.15); - -webkit-box-shadow: 2px 0px 25px rgba(0,0,0,0.15); + left: 0; + box-shadow: 2px 0px 25px rgba(0,0,0,0.15); + -webkit-box-shadow: 2px 0px 25px rgba(0,0,0,0.15); } .sidebar-fixed-right { - right: 0; - box-shadow: 0px 2px 25px rgba(0,0,0,0.15); - -webkit-box-shadow: 0px 2px 25px rgba(0,0,0,0.15); + right: 0; + box-shadow: 0px 2px 25px rgba(0,0,0,0.15); + -webkit-box-shadow: 0px 2px 25px rgba(0,0,0,0.15); - @include translate3d($sidebar-desktop-width, 0, 0); - &.open { - @include translate3d(0, 0, 0); - } - .icon-material-sidebar-arrow:before { - content: "\e614"; // icon-material-arrow-forward - } + @include translate3d($sidebar-desktop-width, 0, 0); + &.open { + @include translate3d(0, 0, 0); + } + .icon-material-sidebar-arrow:before { + content: "\e614"; // icon-material-arrow-forward + } } // Sidebar size // // Change size of sidebar and sidebar elements on small screens @media (max-width: $screen-tablet) { - .sidebar.open { - min-width: $sidebar-width; - width: $sidebar-width; - } + .sidebar.open { + min-width: $sidebar-width; + width: $sidebar-width; + } - .sidebar .sidebar-header { - //height: $sidebar-width * 9/16; // 16:9 header dimension - } + .sidebar .sidebar-header { + //height: $sidebar-width * 9/16; // 16:9 header dimension + } - .sidebar .sidebar-image { - /* img { - width: $sidebar-width/4 - $sidebar-padding; - height: $sidebar-width/4 - $sidebar-padding; - } */ - } + .sidebar .sidebar-image { + /* img { + width: $sidebar-width/4 - $sidebar-padding; + height: $sidebar-width/4 - $sidebar-padding; + } */ + } } .sidebar-overlay { - visibility: hidden; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - opacity: 0; - background: $white; - z-index: $zindex-sidebar-fixed - 1; + visibility: hidden; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + opacity: 0; + background: $white; + z-index: $zindex-sidebar-fixed - 1; - -webkit-transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); - -moz-transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); - transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); - -webkit-transform: translateZ(0); - -moz-transform: translateZ(0); - -ms-transform: translateZ(0); - -o-transform: translateZ(0); - transform: translateZ(0); + -webkit-transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); + -moz-transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); + transition: visibility 0 linear .4s,opacity .4s cubic-bezier(.4,0,.2,1); + -webkit-transform: translateZ(0); + -moz-transform: translateZ(0); + -ms-transform: translateZ(0); + -o-transform: translateZ(0); + transform: translateZ(0); } .sidebar-overlay.active { - opacity: 0.3; - visibility: visible; - -webkit-transition-delay: 0; - -moz-transition-delay: 0; - transition-delay: 0; + opacity: 0.3; + visibility: visible; + -webkit-transition-delay: 0; + -moz-transition-delay: 0; + transition-delay: 0; } diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss index c4105b112..de17e9815 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-utility.scss @@ -19,23 +19,23 @@ $nav-margin-right: 12px; // Mixins @mixin hashi-a-style-core{ - font-family: $header-font-family; - font-weight: $header-font-weight; - font-size: 14px; - //letter-spacing: 0.0625em; + font-family: $header-font-family; + font-weight: $header-font-weight; + font-size: 14px; + //letter-spacing: 0.0625em; } @mixin hashi-a-style{ - margin: 0 15px; - padding: 0; - line-height: 22px; - @include hashi-a-style-core(); - @include transition( all 300ms ease-in ); + margin: 0 15px; + padding: 0; + line-height: 22px; + @include hashi-a-style-core(); + @include transition( all 300ms ease-in ); - &:hover{ - @include transition( all 300ms ease-in ); - background-color: transparent; - } + &:hover{ + @include transition( all 300ms ease-in ); + background-color: transparent; + } } //general shared project mixins @@ -45,10 +45,10 @@ $nav-margin-right: 12px; background-repeat: no-repeat; @media (min--moz-device-pixel-ratio: 1.3), - (-o-min-device-pixel-ratio: 2.6/2), - (-webkit-min-device-pixel-ratio: 1.3), - (min-device-pixel-ratio: 1.3), - (min-resolution: 1.3dppx) { + (-o-min-device-pixel-ratio: 2.6/2), + (-webkit-min-device-pixel-ratio: 1.3), + (min-device-pixel-ratio: 1.3), + (min-resolution: 1.3dppx) { /* on retina, use image that's scaled by 2 */ background-image: url($image); background-size: $width $height; @@ -58,30 +58,30 @@ $nav-margin-right: 12px; // // ------------------------- @mixin anti-alias() { - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; } @mixin open-light() { - font-family: $font-family-open-sans; - font-weight: 300; + font-family: $font-family-open-sans; + font-weight: 300; } @mixin open() { - font-family: $font-family-open-sans; - font-weight: 400; + font-family: $font-family-open-sans; + font-weight: 400; } @mixin open-sb() { - font-family: $font-family-open-sans; - font-weight: 600; + font-family: $font-family-open-sans; + font-weight: 600; } @mixin open-bold() { - font-family: $font-family-open-sans; - font-weight: 700; + font-family: $font-family-open-sans; + font-weight: 700; } @mixin bez-1-transition{ - @include transition( all 300ms ease-in-out ); + @include transition( all 300ms ease-in-out ); } diff --git a/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss b/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss index 80368c269..1a511152d 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss @@ -10,11 +10,11 @@ $project-logo-pad-left: 8px; // Mixins @mixin project-a-style{ - color: $white; - font-weight: 300; - opacity: .75; + color: $white; + font-weight: 300; + opacity: .75; - &:hover{ - color: $white; - } + &:hover{ + color: $white; + } } From ebec7e2bc237a054e751e3d9208da0044bc5e0f4 Mon Sep 17 00:00:00 2001 From: captainill Date: Mon, 9 Nov 2015 22:11:00 -0800 Subject: [PATCH 15/74] use more atomic styles for header/footer classes. use page url to determin class names --- .../source/assets/stylesheets/_footer.scss | 248 ++++--------- .../hashicorp-shared/_hashicorp-header.scss | 345 ++++++++++++------ .../hashicorp-shared/_project-utility.scss | 51 +++ website/source/layouts/_footer.erb | 65 ++-- website/source/layouts/_header.erb | 6 +- 5 files changed, 387 insertions(+), 328 deletions(-) diff --git a/website/source/assets/stylesheets/_footer.scss b/website/source/assets/stylesheets/_footer.scss index c16acff75..c50ce8190 100644 --- a/website/source/assets/stylesheets/_footer.scss +++ b/website/source/assets/stylesheets/_footer.scss @@ -1,210 +1,88 @@ - -#footer-wrap{ - background-color: white; - padding: 0 0 50px 0; -} - -body.page-home{ - #footer{ - margin-top: -40px; - } +body.page-sub{ + #footer{ + padding: 40px 0; + margin-top: 0; + } } #footer{ - padding: 140px 0 40px; - color: black; - - a{ - color: black; - } - + background-color: white; + padding: 100px 0 60px; + margin-top: -40px; + &.white{ + background-color: $black; .footer-links{ - margin-bottom: 20px; - - .li-under a:hover::after, - .li-under a:focus::after { - opacity: 1; - -webkit-transform: skewY(15deg) translateY(8px); - -moz-transform: skewY(15deg) translateY(8px); - transform: skewY(15deg) translateY(8px); - } - - .li-under a::after { - background-color: $purple; - } - - li{ - a{ - text-transform: uppercase; - font-size: 12px; - letter-spacing: 3px; - @include transition( color 0.3s ease ); - font-weight: 400; - - &:hover{ - color: $purple; - @include transition( color 0.3s ease ); - background-color: transparent; - } - } - } + li > a { + @include project-footer-a-subpage-style(); + } } + } - .buttons.navbar-nav{ - float: none; - display: inline-block; - margin-bottom: 30px; - margin-top: 0px; - - li{ - &.first{ - margin-right: 12px; - } - - &.download{ - a{ - background: image-url('icon-download-purple.png') 8px 6px no-repeat; - @include img-retina("icon-download-purple.png", "icon-download-purple@2x.png", 20px, 20px); - } - } - - &.github{ - a{ - background: image-url('icon-github-purple.png') 8px 6px no-repeat; - @include img-retina("icon-github-purple.png", "icon-github-purple@2x.png", 20px, 20px); - } - } - } - - li > a { - padding-top: 6px; - padding-bottom: 6px; - padding-left: 40px; - } + .footer-links{ + li > a { + @include project-footer-a-style(); } + } - .footer-hashi{ - float: right; - padding-top: 5px; - letter-spacing: 2px; + .hashicorp-project{ + margin-top: 24px; + } - a{ - color: black; - font-weight: $font-weight-lato-xb; - } - - span{ - margin-right: 10px; - } - - .hashi-logo{ - display: inline-block; - vertical-align: middle; - i{ - display: inline-block; - width: 37px; - height: 40px; - background: image-url('footer-hashicorp-logo.png') 0 0 no-repeat; - @include img-retina("footer-hashicorp-logo.png", "footer-hashicorp-logo@2x.png", 37px, 40px); - } - } - } + .pull-right{ + padding-right: 15px; + } } -.page-sub{ - #footer-wrap{ - padding: 0; - } +.edit-page-link{ + position: absolute; + top: -70px; + right: 30px;; - #footer{ - padding: 140px 0 100px; - background-color: $black; - transform: none; - - >.container{ - transform: none; - } - - a{ - color: white; - } - - .footer-hashi{ - color: white; - - .hashi-logo{ - i{ - background: image-url('footer-hashicorp-white-logo.png') 0 0 no-repeat; - @include img-retina("footer-hashicorp-white-logo.png", "footer-hashicorp-white-logo@2x.png", 37px, 40px); - } - } - } - } -} - - -@media (min-width: 1500px) { - body.page-home{ - #footer{ - margin-top: -60px; - padding: 190px 0 40px; - } - } + a{ + text-transform: uppercase; + color: $black; + font-size: 13px; + } } @media (max-width: 992px) { - .page-sub #footer, #footer{ - .footer-hashi { - padding-top: 14px; - span{ - margin-right: 6px; - } - .hashi-logo{ - i{ - margin-top: -6px; - width: 20px; - height: 22px; - background-size: 20px 22px; - } - } - } + .footer-links { + display: block; + text-align: center; + + ul{ + display: inline-block;; + float: none !important; } - -} - -@media (max-width: 768px) { - #footer{ - padding: 100px 0 40px; - text-align: center; - - .footer-links{ - float: none; - display: inline-block; - } - - .footer-hashi { - float: none; - display: inline-block; - - .pull-right{ - float: none !important; - } - } + .footer-hashi{ + display: block; + float: none !important; } + } } -@media (max-width: 320px) { - #footer{ - text-align: center; +@media (max-width: 414px) { + #footer{ + ul{ + display: block; + li{ + display: block; + float: none; + } - .footer-links{ - .li-under{ - float: none !important; - } + &.external-links{ + li{ + svg{ + position: relative; + left: 0; + top: 2px; + margin-top: 0; + margin-right: 4px; + } } + } } + } } - - diff --git a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss index c9bc593b6..e9bbe501e 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_hashicorp-header.scss @@ -4,33 +4,21 @@ // - Edits should not be made here // -------------------------------------------------- -#header { +#header{ position: relative; + margin-bottom: 0; +} + +.navigation { color: black; text-rendering: optimizeLegibility; - margin-bottom: 0; transition: all 1s ease; &.white{ - color: white; .navbar-brand { .logo { color: white; } - - .by{ - color: white; - font-weight: 300; - svg{ - path, - polygon{ - fill: white; - } - line{ - stroke: white; - } - } - } } .main-links, @@ -41,109 +29,40 @@ } } } + } - .nav > li > a:hover, .nav > li > a:focus { - color: white; + &.black{ + .navbar-brand { + .logo { + color: black; + } } - .navbar-header{ - .navbar-toggle{ - .icon-bar{ - border: 1px solid white; - } + .main-links, + .external-links { + li > a { + color: black; } } } - .navbar-header{ - .navbar-toggle{ - height: $header-height; - margin: 0; - padding-right: 15px; - border-radius: 0; - .icon-bar{ - border: 1px solid $black; - border-radius: 0; - } - } - } - - .navbar-brand { - display: block; + .navbar-toggle{ height: $header-height; - padding: 0; - margin: 0 10px 0 0 ; - - .logo{ - display: inline-block; - height: $header-height; - vertical-align:top; - padding: 0; - line-height: $header-height; - padding-left: $project-logo-width + $project-logo-pad-left; - background-position: 0 center; - @include transition(all 300ms ease-in); - - &:hover{ - @include transition(all 300ms ease-in); - text-decoration: none; - } - } - - .by{ - display: inline-block; - vertical-align:top; - height: $header-height; - margin-left: 3px; - padding-top: 2px; - color: black; - line-height: $header-height; - font-family: $header-font-family; - font-weight: 600; - font-size: 0; - text-decoration: none; - - .svg-wrap{ - font-size: 13px; - } - - svg{ - &.svg-by{ - width: $by-hashicorp-width; - height: $by-hashicorp-height; - margin-bottom: -4px; - margin-left: 4px; - } - - &.svg-logo{ - width: 16px; - height: 16px; - margin-bottom: -3px; - margin-left: 4px; - } - - path, - polygon{ - fill: black; - @include transition(all 300ms ease-in); - - &:hover{ - @include transition(all 300ms ease-in); - } - } - line{ - stroke: black; - @include transition(all 300ms ease-in); - - &:hover{ - @include transition(all 300ms ease-in); - } - } - } + margin: 0; + border-radius: 0; + .icon-bar{ + border: 1px solid $black; + border-radius: 0; } } .external-links { + &.white{ + svg path{ + fill: $white; + } + } + li { position: relative; @@ -157,6 +76,8 @@ } } + @include project-svg-external-links-style(); + &.download{ margin-right: 10px; } @@ -181,28 +102,222 @@ .main-links, .external-links { + &.white{ + li > a { + color: white; + } + } li > a { @include hashi-a-style(); margin: 0 10px; padding-top: 1px; line-height: $header-height; + @include project-a-style(); } } .nav > li > a:hover, .nav > li > a:focus { background-color: transparent; - color: $black; @include transition( all 300ms ease-in ); } } +.navbar-brand { + display: block; + height: $header-height; + padding: 0; + margin: 0 10px 0 0; + + .logo{ + display: inline-block; + height: $header-height; + vertical-align:top; + padding: 0; + line-height: $header-height; + padding-left: $project-logo-width + $project-logo-pad-left; + background-position: 0 center; + @include transition(all 300ms ease-in); + + &:hover{ + @include transition(all 300ms ease-in); + text-decoration: none; + } + } +} + +.navbar-toggle{ + &.white{ + .icon-bar{ + border: 1px solid white; + } + } +} + +.by-hashicorp{ + display: inline-block; + vertical-align:top; + height: $header-height; + margin-left: 3px; + padding-top: 2px; + color: black; + line-height: $header-height; + font-family: $header-font-family; + font-weight: 600; + font-size: 0; + text-decoration: none; + + &.white{ + color: white; + font-weight: 300; + svg{ + path, + polygon{ + fill: white; + } + line{ + stroke: white; + } + } + + &:focus, + &:hover{ + text-decoration: none; + color: white; + } + } + + &:focus, + &:hover{ + text-decoration: none; + } + + .svg-wrap{ + font-size: 13px; + } + + svg{ + &.svg-by{ + width: $by-hashicorp-width; + height: $by-hashicorp-height; + margin-bottom: -4px; + margin-left: 4px; + } + + &.svg-logo{ + width: 16px; + height: 16px; + margin-bottom: -3px; + margin-left: 4px; + } + + path, + polygon{ + fill: black; + @include transition(all 300ms ease-in); + + &:hover{ + @include transition(all 300ms ease-in); + } + } + line{ + stroke: black; + @include transition(all 300ms ease-in); + + &:hover{ + @include transition(all 300ms ease-in); + } + } + } +} + +.hashicorp-project{ + display: inline-block; + height: 30px; + line-height: 30px; + text-decoration: none; + font-size: 14px; + color: $black; + font-weight: 600; + + &.white{ + color: white; + svg{ + path, + polygon{ + fill: white; + } + line{ + stroke: white; + } + } + } + + &:focus{ + text-decoration: none; + } + + &:hover{ + text-decoration: none; + svg{ + &.svg-by{ + line{ + stroke: $purple; + } + } + } + } + + span{ + margin-right: 4px; + font-family: $header-font-family; + font-weight: 500; + } + + span, + svg{ + display: inline-block; + } + + svg{ + &.svg-by{ + width: $by-hashicorp-width; + height: $by-hashicorp-height; + margin-bottom: -4px; + margin-left: -3px; + } + + &.svg-logo{ + width: 30px; + height: 30px; + margin-bottom: -10px; + margin-left: -1px; + } + + path, + line{ + fill: $black; + @include transition(all 300ms ease-in); + + &:hover{ + @include transition(all 300ms ease-in); + } + } + } +} + +@media (max-width: 480px) { + .navigation { + .main-links{ + margin-right: 0; + } + } +} + @media (max-width: 414px) { #header { - .navbar-header{ - .navbar-toggle{ - padding-top: 10px; - height: $header-mobile-height; - } + .navbar-toggle{ + padding-top: 10px; + height: $header-mobile-height; } .navbar-brand { @@ -212,7 +327,7 @@ height: $header-mobile-height; line-height: $header-mobile-height; } - .by{ + .by-hashicorp{ height: $header-mobile-height; line-height: $header-mobile-height; padding-top: 0; diff --git a/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss b/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss index 1a511152d..5e51f91d5 100755 --- a/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss +++ b/website/source/assets/stylesheets/hashicorp-shared/_project-utility.scss @@ -16,5 +16,56 @@ $project-logo-pad-left: 8px; &:hover{ color: $white; + opacity: 1; + } +} + +@mixin project-footer-a-style{ + color: $black; + font-weight: 400; + + &:hover{ + color: $purple; + + svg path{ + fill: $purple; + } + } +} + +@mixin project-footer-a-subpage-style{ + color: $white; + font-weight: 400; + + svg path{ + fill: $white; + } + + &:hover{ + color: $purple; + + svg path{ + fill: $purple; + } + } +} + +@mixin project-svg-external-links-style{ + svg path{ + fill: $black; + } + + &:hover{ + svg path{ + fill: $blue; + } + } +} + +@mixin project-by-hashicorp-style{ + &:hover{ + line{ + stroke: $blue; + } } } diff --git a/website/source/layouts/_footer.erb b/website/source/layouts/_footer.erb index d42c55cac..1be5b8d47 100644 --- a/website/source/layouts/_footer.erb +++ b/website/source/layouts/_footer.erb @@ -1,28 +1,43 @@ - +