assetdetails

PHOTO EMBED

Wed Jul 17 2024 07:21:44 GMT+0000 (Coordinated Universal Time)

Saved by @faizan

import React, { useCallback, useEffect, useState } from 'react';
import { NavLink, useParams } from 'react-router-dom';
import Loader from '../common/components/Loader';
import { IRouteParams } from '../common/interfaces/IRouteParams';
import Repository from '../common/repository/repository';
import { AssetType, IAsset } from './interfaces/IAsset';
import styled from 'styled-components';
import config from '../config.json';
import Title from '../common/components/LayoutComponents/Title';
// import { Button, Col, Input, Row, UncontrolledAlert } from 'reactstrap';
import { Button, Col, Form, FormGroup, Input, Label, Row, UncontrolledAlert } from 'reactstrap';
import Asset from '../composition_riv/components/Asset';
import { IApiPostResponse } from '../common/interfaces/IApiPostResponse';
import { formatDateString } from '../common/utils/Date';
import AppRoutes from '../AppRoutes';
import { useTranslations } from '../i18n/useTranslations';
import * as Constants from "../common/constants/library-constants";
import * as Global_Constants from "../common/constants/shared-constants";
import * as Dam_Constants from "../digital_assets_management/constants/dam-constants";

const AssetContainer = styled.div`
  overflow-y: auto;
  height:100%;
  
`;

const AssetDiv = styled.div`
  display: flex;
  flex-direction: column;
`;

const AssetIllustration = styled.div`
  width: 100%;
  max-height: 270px;
  height: 270px;
  display: flex;
  justify-content: center;

  .sdc-asset {
    &.sdc-playlist {
      height: 100%;
      width: 100%;
    }
  }
`;

const AssetPropertyTitle = styled.div`
  width: 100%;
  font-weight: bold;
  justify-content: top;
`;

const AssetTagsContainer = styled.div`
  width: 100%;
  display: flex;
  width: 9rem;
`;

const TagContainer = styled.div.attrs({
  'data-testid': 'new-asset-tag-container',
})`
  display: flex;
  align-items: center;
  width: 9rem;
  padding-bottom: 0.25rem;
`;
const ScrollableContainer = styled.div`
 	 max-height: 270px;
 		  overflow-y: auto;
 		  width: 100%;
 		`;
const TagsList = styled.div.attrs({
  className: 'col-sm-9',
})`
  display: flex;
  flex-wrap: wrap;
`;

const TagButton = styled.i`
  cursor: pointer;
  padding: 0.25rem 0.5rem;
  color: darkred;
`;

export const AssetDetails = () => {
  const i18n = useTranslations()
  const [changeNameErrorMessage, setChangeNameErrorMessage] = useState('');
  const [tagsErrorMessage, setTagsErrorMessage] = useState('');
  const [resultLoaded, setResultLoaded] = useState(false);
  const [assetVersions, setAssetVersions] = useState([] as IAsset[]);
  const [selectedAsset, setSelectedAsset] = useState(null as unknown as IAsset);
  const [selectedAssetIndex, setSelectedAssetIndex] = useState(0);
  const [selectedAssetRoute, setSelectedAssetRoute] = useState<
    string | undefined
  >('');
  const [showEditNameForm, setShowEditNameForm] = useState(false);
  const [newAssetName, setNewAssetName] = useState('');
  const [newTag, setNewTag] = useState('');
  const [sequencesForScene, setSequencesForScene] = useState<IAsset[]>([]);
  const { id } = useParams<IRouteParams>();

  const retrieveAssetVersions = useCallback(async () => {
    setResultLoaded(false);

    const assets = await Repository.getInstance().getAssetVersions(
      parseInt(id)
    );

    setAssetVersions(assets);
    if (
      assets !== null &&
      assets[selectedAssetIndex] !== undefined &&
      assets[selectedAssetIndex] !== null
    ) {
      setSelectedAsset(assets[selectedAssetIndex]);
      setSelectedAssetRoute(assetToRoute(assets[selectedAssetIndex]));
    } else {
      setSelectedAsset(null as unknown as IAsset);
    }
    setResultLoaded(true);
  }, [id, selectedAssetIndex]);

  useEffect(() => {
    retrieveAssetVersions();
  }, [retrieveAssetVersions]);

  useEffect(() => {
    if (!selectedAsset) return;
    if (selectedAsset.file_type !== AssetType.Scene) return;
    const retrieveSequences = async () => {
      const sequenceNames =
        await Repository.getInstance().getSequencesUsingScene(
          selectedAsset.name
        );
      setSequencesForScene(sequenceNames);
    };
    retrieveSequences();
  }, [selectedAsset]);

  function changeSelectedVersion(e: React.ChangeEvent<HTMLInputElement>) {
    const selectedId = e.target.value;
    const selectedIndex = assetVersions.findIndex((ast) => ast.id.toString() === selectedId);
    setSelectedAssetIndex(selectedIndex);
  }

  function toggleEditNameForm() {
    setShowEditNameForm(!showEditNameForm);
  }

  function changeNewAssetName(evt: React.ChangeEvent<HTMLInputElement>) {
    setNewAssetName(evt.target.value);
  }

  function changeNewTag(evt: React.ChangeEvent<HTMLInputElement>) {
    setNewTag(evt.target.value);
  }

  function validateNewNameForm() {
    return newAssetName !== '' && newAssetName !== selectedAsset?.name;
  }

  async function sendNewName() {
    setChangeNameErrorMessage('');
    setResultLoaded(false);

    const data = new FormData();
    data.append('newName', newAssetName);
    const apiResponse = new IApiPostResponse();
    await Repository.getInstance().editAssetName(
      selectedAsset?.id,
      data,
      apiResponse,
      i18n(Global_Constants.GLOBAL, Dam_Constants.CHECK_NETWORK_STATUS)
    );
    if (apiResponse.errorMessage != null) {
      setChangeNameErrorMessage(apiResponse.errorMessage);
    }
    await retrieveAssetVersions();
  }

  async function removeTag(tagId: number) {
    setResultLoaded(false);
    await Repository.getInstance().removeTagFromAsset(selectedAsset?.id, tagId);
    await retrieveAssetVersions();
  }

  async function addTag(tagName: string) {
    if (selectedAsset?.tags.findIndex((t) => t.name === tagName) !== -1) return;

    setTagsErrorMessage('');
    setResultLoaded(false);

    const data = new FormData();
    data.append('assetId', selectedAsset?.id.toString());
    data.append('tagName', tagName);

    const apiResponse = new IApiPostResponse();
    await Repository.getInstance().addTagToAsset(data, apiResponse);
    if (apiResponse.errorMessage != null) {
      setTagsErrorMessage(apiResponse.errorMessage);
    }
    setNewTag('');
    await retrieveAssetVersions();
  }

  const setAssetIsSubstitution = async (checked: boolean) => {
    setResultLoaded(false);
    if (checked)
      await Repository.getInstance().setIsSubstitutionAsset(selectedAsset.id);
    else
      await Repository.getInstance().UnsetIsSubstitutionAsset(selectedAsset.id);
    await retrieveAssetVersions();
  };

  const assetTypeToDescription = (assetType: AssetType) => {
    const types = new Map([
      [AssetType.Image, 'Image'],
      [AssetType.Scene, 'Scene'],
      [AssetType.Sound, 'Son'],
      [AssetType.Video, 'Vidéo'],
      [AssetType.Sequence, 'Séquence'],
      [AssetType.Text, 'Texte'],
      [AssetType.Font, 'Police'],
      [AssetType.Style, 'Style'],
      [AssetType.PredefMessage, 'Message'],
      [AssetType.Programmation, 'Programmation'],
    ]);
    return types.get(assetType);
  };

  const assetToRoute = (asset: IAsset) => {
    const types = new Map([
      [AssetType.Sequence, AppRoutes.sequence(asset.id.toString())],
      [AssetType.Scene, AppRoutes.editor(asset.id.toString())],
      [
        AssetType.PredefMessage,
        AppRoutes.predefinedMessage(asset.id.toString()),
      ],
      [AssetType.Playlist, AppRoutes.audioPlaylist(asset.id.toString())],
      [AssetType.Style, AppRoutes.style(asset.id.toString())],
      [AssetType.Programmation, AppRoutes.programmation(asset.id.toString())],
    ]);

    return types.get(asset.file_type);
  };

  return (
    <AssetContainer>
      {!resultLoaded && <Loader />}
      <Title>{i18n(Global_Constants.LIBRARY, Constants.RESOURCE_DETAILS)}: {selectedAsset?.name}</Title>
      <Form>
        <AssetDiv>
          <AssetIllustration>
            {selectedAsset && <Asset asset={selectedAsset} />}
          </AssetIllustration>

          <FormGroup row >
            <Label for="version" sm={3}><AssetPropertyTitle>Version</AssetPropertyTitle></Label>
            <Col sm={3}>
              <Input
                type="select"
                id="version"
                value={selectedAsset?.id}
                onChange={changeSelectedVersion}
                disabled={!assetVersions || !assetVersions.length || assetVersions.length === 1}
              >
                {assetVersions?.map((asset, index) => (
                  <option key={`${asset.version}-${index}`} value={asset.id}>
                    {asset.version}
                  </option>
                ))}
              </Input>
            </Col>
          </FormGroup>

          <FormGroup row>
            <Label for="assetName" sm={3}><AssetPropertyTitle>{i18n(Global_Constants.GLOBAL, Global_Constants.NAME)}</AssetPropertyTitle></Label>
            <Col sm={3}>
              <div className="d-flex align-items-center">
                {selectedAsset?.name}
                <i
                  className={`ms-1 fa fa-lg fa-pencil-square${showEditNameForm ? '' : '-o'}`}
                  style={{ cursor: 'pointer' }}
                  onClick={toggleEditNameForm}
                />
              </div>
            </Col>
          </FormGroup>

          {showEditNameForm && (
            <FormGroup row>
              <Label for="newAssetName" sm={3}><AssetPropertyTitle>{i18n(Global_Constants.LIBRARY, Constants.NEW_NAME)}</AssetPropertyTitle></Label>
              <Col sm={3}>
                <Input
                  type="text"
                  id="newAssetName"
                  value={newAssetName}
                  onChange={changeNewAssetName}
                  placeholder={selectedAsset.name}
                />
                <Button
                  className="btn btn-danger mt-1"
                  disabled={!validateNewNameForm()}
                  onClick={sendNewName}
                >
                  {i18n(Global_Constants.LIBRARY, Global_Constants.CHANGE)}
                </Button>
              </Col>
              {changeNameErrorMessage && (
                <UncontrolledAlert color="danger">
                  Error: {changeNameErrorMessage}
                </UncontrolledAlert>
              )}
            </FormGroup>
          )}

          <FormGroup row>
            <Label for="creationDate" sm={3}><AssetPropertyTitle>{i18n(Global_Constants.GLOBAL, Global_Constants.CREATION_DATE)}</AssetPropertyTitle></Label>
            <Col sm={3}>
              <Input type="text" id="creationDate" value={formatDateString(selectedAsset?.created_at)} readOnly />
            </Col>
          </FormGroup>

          <FormGroup row>
            <Label for="modificationDate" sm={3}><AssetPropertyTitle>{i18n(Global_Constants.GLOBAL, Global_Constants.LAST_MODIFICATION_DATE)}</AssetPropertyTitle></Label>
            <Col sm={3}>
              <Input type="text" id="modificationDate" value={formatDateString(selectedAsset?.updated_at)} readOnly />
            </Col>
          </FormGroup>

          <FormGroup row>
            <Label for="resourceType" sm={3}><AssetPropertyTitle>{i18n(Global_Constants.LIBRARY, Constants.RESOURCE_TYPE)}</AssetPropertyTitle></Label>
            <Col sm={3}>
              <Input type="text" id="resourceType" value={assetTypeToDescription(selectedAsset?.file_type)} readOnly />
            </Col>
          </FormGroup>

          <FormGroup row>
            <Label for="dimension" sm={3}><AssetPropertyTitle>{i18n(Global_Constants.LIBRARY, Constants.SIZE)}</AssetPropertyTitle></Label>
            <Col sm={3}>
              <Input type="text" id="dimension" value={String(selectedAsset?.dimension)} readOnly />
            </Col>
          </FormGroup>

          {selectedAsset && (selectedAsset?.file_type === AssetType.Image || selectedAsset?.file_type === AssetType.Text || selectedAsset?.file_type === AssetType.Style) && (
            <FormGroup row>
              <Label for="substitute" sm={3}><AssetPropertyTitle>{i18n(Global_Constants.LIBRARY, Constants.SUBSTITUTE_MESSAGE)}</AssetPropertyTitle></Label>
              <Col sm={3}>
                <Input
                  id="isSubstitution"
                  type="checkbox"
                  className="form-check-input"
                  checked={selectedAsset?.isSubstitution ?? false}
                  onChange={(e) => setAssetIsSubstitution(e.target.checked)}
                />
              </Col>
            </FormGroup>
          )}

          <FormGroup row>
            <Label for="keywords" sm={3}><AssetPropertyTitle>{i18n(Global_Constants.LIBRARY, Constants.KEYWORDS)}</AssetPropertyTitle></Label>
            <Col sm={3}>
              <AssetTagsContainer>
                <TagsList>
                  {selectedAsset?.tags.map((tag, i) => (
                    <TagContainer key={`asset-tag-${selectedAsset.name}-${i}`}>
                      <Input type="text" value={tag.name} readOnly />
                      <TagButton className="fa fa-xs fa-close" onClick={() => removeTag(tag.id)} />
                    </TagContainer>
                  ))}
                  <TagContainer>
                    <Input
                      type="text"
                      id="new-asset-tag"
                      value={newTag}
                      placeholder={i18n(Global_Constants.LIBRARY, Constants.KEYWORD)}
                      onChange={changeNewTag}
                    />
                    <TagButton className={`fa fa-plus ${newTag === '' ? 'sdc-disabled' : ''}`} onClick={() => addTag(newTag)} />
                  </TagContainer>
                </TagsList>
              </AssetTagsContainer>
              {tagsErrorMessage && (
                <UncontrolledAlert color="danger">
                  Error: {tagsErrorMessage}
                </UncontrolledAlert>
              )}
            </Col>
          </FormGroup>

          {selectedAsset?.file_type === AssetType.Scene && sequencesForScene.length > 0 && (
            <FormGroup row>
              <Label for="sequences" sm={3}><AssetPropertyTitle>Utilized in sequences</AssetPropertyTitle></Label>
              <Col sm={3}>
                {sequencesForScene.map((s) => (
                  <div key={`seq-for-scene-${s.name}`}>
                    <NavLink to={AppRoutes.assetDetails(s.id.toString())}>
                      {s.name}
                    </NavLink>
                  </div>
                ))}
              </Col>
            </FormGroup>
          )}

          {selectedAssetRoute && (
            <div>
              <NavLink className="btn btn-secondary" to={selectedAssetRoute}>
                {i18n(Global_Constants.INFORMATION, Global_Constants.MODIFY_BUTTON)}
              </NavLink>
            </div>
          )}
        </AssetDiv>
      </Form>
    </AssetContainer>
  );
};

export default AssetDetails;
content_copyCOPY