---
include:
  - docassemble.ALToolbox:display_template.yml
  - nav.yml
---
metadata:
  title: Compile Bootstrap Themes
  sessions are unique: True
  required privileges:
    - admin
    - developer
  temporary session: True
---
objects:
  - output_file: DAFile
  - output_scss: DAFile.using(filename="custom.scss")
  - test_html_file: DAStaticFile.using(filename="test_html.html")
---
id: interview order block
mandatory: True
code: |
  start_screen
  installed
  upload_choice
  compiled
  done
---
code: |
  bootstrap_dir = "/tmp/bootstrap-5.3.0/"
---
need:
  - bootstrap_dir
code: |
  # Should be a background task
  import requests, zipfile, io
  import subprocess
  from pathlib import Path
  # https://stackoverflow.com/a/14260592
  p = Path(bootstrap_dir)
  if not p.is_dir():
      r = requests.get("https://github.com/twbs/bootstrap/archive/refs/tags/v5.3.0.zip")
      z = zipfile.ZipFile(io.BytesIO(r.content))
      z.extractall("/tmp/")
      z.close()
      del z
      subprocess.run(["npm", "install", "--prefix", bootstrap_dir])
  installed = True
---
need:
  - bootstrap_dir
  - upload_choice
  - output_file
code: |
  import shutil, uuid, os, subprocess
  from pathlib import Path
  file_name = uuid.uuid4()
  full_path = os.path.join(bootstrap_dir, "scss", f"{file_name}.scss")
  if upload_choice == "type_out":
    with open(full_path, "w") as text_to_file:
      text_to_file.write(file_text)
    output_scss.copy_into(full_path)
  else: # upload_file
    shutil.copy(uploaded_file.path(), os.path.join(bootstrap_dir, "scss", f"{file_name}.scss"))
  compile_output = subprocess.run(["npm", "run", "css-compile", "--prefix", bootstrap_dir], capture_output=True)
  os.remove(full_path)
  out_path = Path(bootstrap_dir + f"dist/css/{file_name}.css")
  if not out_path.is_file():
    error_screen
  output_file.initialize(filename="custom.css")
  output_file.copy_into(bootstrap_dir + f"dist/css/{file_name}.css")
  output_file.commit()
  compiled = True
---
id: start-page
comment: |
  Mostly here to prevent docassemble from auto downloading bootstrap in the playground / on load
question: |
  Create a custom theme for Bootstrap
subquestion: |
  This interview will let you create a custom bootstrap theme, compiling it down into a single
  CSS file that you can include in your docassemble projects.

  For more information, see [our tutorial on making a custom bootstrap theme](https://suffolklitlab.org/legal-tech-class/docs/practical-guide-docassemble/theming-docassemble#creating-a-custom-theme-from-source-instead-of-with-a-theme-generator).

  If your Docassemble "system" version is less than 1.4.43, you will need to upgrade (yours is ${ get_config("system version") }).
  This requires an upgrade to the [Docker container](https://suffolklitlab.org/legal-tech-class/docs/practical-guide-docassemble/maintaining-docassemble#updates-to-the-docassemble-container).
continue button field: start_screen
---
id: file-upload
question: |
  What file do you want to make a theme from?
subquestion: |
  It should include an `@import "bootstrap"` in it to actually include all of the bootstrap code.

  You can use [https://huemint.com/bootstrap-basic/](https://huemint.com/bootstrap-basic/)
  to generate the SCSS code.
fields:
  - How do you want to provide the file?: upload_choice
    datatype: radio
    choices:
      - Upload file: upload_file
      - Type it out here: type_out
  - SCSS file: uploaded_file
    datatype: file
    accept: |
      "text/x-sass,text/x-scss,.sass,.scss"
    show if:
      variable: upload_choice
      is: "upload_file"
  - note: |
      Type the contents of your bootstrap theme below
    show if:
      variable: upload_choice
      is: type_out
  - no label: file_text
    input type: area
    rows: 15
    show if:
      variable: upload_choice
      is: type_out
    default: |
        $white: #ffffff;
        $blue: #0d6efd;

        $theme-colors: (
            "light":      #f8f9fa,
            "dark":       #212529,
            "primary":    #0d6fed,
            "secondary":  #6c757,
            "info":       #0dcaf0,
            "success":    #198754,
            "warning":    #ffc107,
            "danger":     #dc3545,
        );
        @import "bootstrap";
validation code: |
  if upload_choice == "type_out" and not '@import "bootstrap";' in file_text:
    validation_error('You need to include the exact text \'@import "bootstrap";\' at the end of your SCSS block', field="file_text")
---
template: output_template
subject: Bootstrap CSS Contents
content: |
  ${ output_file.slurp() }
---
event: error_screen
question: We weren't able to compile your SCSS
subquestion: |
  Bootstrap returned this output when we tried to create your Bootstrap CSS file.

  <pre>
  ${ compile_output.stderr.decode() }
  </pre>
---
event: done
id: done
question: |
  Your file is compiled!
subquestion: |
  You can view and copy your file, or download it directly by right clicking the link to save it as a CSS file.

  ${ display_template(output_template, copy=True, collapse=True) }

  **[Bootstrap CSS file](${output_file.url_for(attachment=True)})**

  % if upload_choice == "type_out":
  **[:download: SCSS source file](${ output_scss.url_for(attachment=True) })**
  % else:
  **[:download: SCSS source file](${ uploaded_file.url_for(attachment=True) })**
  % endif

  <br>

  ---

  Below are examples of all bootstrap components and what they will look like with this
  bootstrap theme.

  ${ test_html_file.slurp() }

  ---

script: |
  <script type="text/javascript">
    var link = document.createElement('link');
    link.setAttribute('rel', 'stylesheet');
    link.setAttribute('href', '${ output_file.url_for() }');
    document.head.appendChild(link);
  </script>
css: |
  <style>
    #daquestion {
      margin-left: 0% !important;
      width: 100% !important;
    }
    .bs-component + .bs-component {
      margin-top: 1rem;
    }
  </style>
