github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/pkg/cloud/dashboard/src/components/image_list.rs (about)

     1  // Copyright © 2021 Alibaba Group Holding Ltd.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  use crate::routes::{router::Anchor, router::AppRoute};
    16  use crate::services::requests::{Image, Images, RegistryCatalog};
    17  use yew::services::ConsoleService;
    18  use serde::Deserialize;
    19  use yew::{
    20      format::{Json, Nothing},
    21      html,
    22      services::fetch::{FetchService, FetchTask, Request, Response},
    23      Component, ComponentLink, Html, ShouldRender,
    24  };
    25  
    26  #[derive(Debug)]
    27  pub enum Msg {
    28      GetRegistryCatelog(Result<RegistryCatalog, anyhow::Error>),
    29  }
    30  
    31  enum Class {
    32      Provider,
    33      Categories,
    34      OperatingSystems,
    35      Architectrues,
    36  }
    37  
    38  enum Label {
    39      ThirdPart(Class, String),
    40      Official(Class, String),
    41  
    42      Analytics(Class, String),
    43      ApplicationRuntime(Class, String),
    44      BaseImages(Class, String),
    45      Databases(Class, String),
    46      DevOps(Class, String),
    47      Messaging(Class, String),
    48      Monitoring(Class, String),
    49      OperatingSystem(Class, String),
    50      Storage(Class, String),
    51      Networking(Class, String),
    52  
    53      Linux(Class, String),
    54      Windows(Class, String),
    55  
    56      ARM64(Class, String),
    57      AMD64(Class, String),
    58  }
    59  
    60  impl Component for Images {
    61      type Message = Msg;
    62      type Properties = ();
    63  
    64      fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
    65          ConsoleService::info("create app");
    66          Self {
    67              repos: None,
    68              link,
    69              error: None,
    70              task: None,
    71          }
    72      }
    73  
    74      fn update(&mut self, msg: Self::Message) -> ShouldRender {
    75          use Msg::*;
    76          match msg {
    77              GetRegistryCatelog(response) => match response {
    78                  Ok(repos) => {
    79                      ConsoleService::info(&format!("info {:?}", repos)); 
    80                      self.repos = Some(repos.repositories);
    81                  }
    82                  Err(error) => {
    83                      ConsoleService::info(&format!("info {:?}", error.to_string())); 
    84                  },
    85              },
    86          }
    87          true
    88      }
    89  
    90      fn rendered(&mut self, first_render: bool) {
    91          if first_render {
    92              ConsoleService::info("view app");
    93              let request = Request::get("http://localhost:8001/v2/_catalog")
    94                  .body(Nothing)
    95                  .expect("could not build request.");
    96              let callback = self.link.callback(
    97                  |response: Response<Json<Result<RegistryCatalog, anyhow::Error>>>| {
    98                      let Json(data) = response.into_body();
    99                      Msg::GetRegistryCatelog(data)
   100                  },
   101              );
   102              let task = FetchService::fetch(request, callback).expect("failed to start request");
   103              self.task = Some(task);
   104          }
   105      }
   106  
   107      fn change(&mut self, props: Self::Properties) -> ShouldRender {
   108          true
   109      }
   110  
   111      fn view(&self) -> Html {
   112          html! {
   113            <div>
   114            <div class="columns is-multiline">
   115              <div class="container column is-1">
   116                { self.filter() }
   117              </div>
   118              <div class="container column is-10">
   119              { self.image_list() }
   120              </div>
   121            </div>
   122            </div>
   123          }
   124      }
   125  
   126      fn destroy(&mut self) {}
   127  }
   128  
   129  impl Images {
   130      fn filter(&self) -> Html {
   131          html! {
   132           <aside class="menu">
   133               <p class="menu-label">
   134                { "Provider" }
   135               </p>
   136               <ul class="menu-list">
   137               <li><a>{ "Official" }</a></li>
   138               <li><a>{ "ThirdPart" }</a></li>
   139               </ul>
   140               <p class="menu-label">
   141                 { "Categories" }
   142               </p>
   143               <ul class="menu-list">
   144               <li><a>{ "BaseImage" }</a></li>
   145               <li><a>{ "DataBases" }</a></li>
   146               <li><a>{ "Messaging" }</a></li>
   147               <li><a>{ "Monitoring" }</a></li>
   148               </ul>
   149               <p class="menu-label">
   150                 { "Architecutures" }
   151               </p>
   152               <ul class="menu-list">
   153               <li><a>{ "ARM64" }</a></li>
   154               <li><a>{ "AMD64" }</a></li>
   155               </ul>
   156           </aside>
   157          }
   158      }
   159      fn image_list(&self) -> Html {
   160          match &self.repos {
   161              Some(images) => {
   162                  html! {
   163                   <div class="columns is-multiline">
   164                     {
   165                         for images.iter().map(|image|{
   166                             self.image_info(image)
   167                         })
   168                     }
   169                   </div>
   170                  }
   171              }
   172              None => {
   173                  html! {
   174                    <p> {"image not found"} </p>
   175                  }
   176              }
   177          }
   178      }
   179  
   180      fn image_info(&self, image: &String) -> Html {
   181          html! {
   182           <div class="column is-6">
   183             <div class="card">
   184             <Anchor route=AppRoute::ImageDetail(image.to_string())>
   185               <header class="card-header">
   186                 <p class="card-header-title">
   187                   { image.to_string() }
   188                 </p>
   189                 <button class="card-header-icon" aria-label="more options">
   190                 <span class="icon">
   191                   <i class="fal fa-expand" aria-hidden="true"></i>
   192                 </span>
   193               </button>
   194               </header>
   195               </Anchor>
   196                 <div class="card-content">
   197                 <div class="content">
   198                   { "describe" }
   199                    <br />
   200                   <time datetime="2016-1-1">{ "11:09 PM - 1 Jan 2016" }</time>
   201                 </div>
   202                 </div>
   203              </div>
   204           </div>
   205          }
   206      }
   207  }